]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-arm
authorTom Rini <trini@ti.com>
Mon, 14 Oct 2013 15:20:32 +0000 (11:20 -0400)
committerTom Rini <trini@ti.com>
Mon, 14 Oct 2013 15:20:32 +0000 (11:20 -0400)
185 files changed:
Licenses/README
Makefile
README
arch/arm/cpu/arm926ejs/at91/eflash.c
arch/arm/cpu/arm926ejs/kirkwood/cpu.c
arch/arm/cpu/armv7/at91/sama5d3_devices.c
arch/arm/cpu/armv7/exynos/clock.c
arch/arm/cpu/armv7/exynos/pinmux.c
arch/arm/cpu/armv7/nonsec_virt.S
arch/arm/cpu/armv7/omap5/hw_data.c
arch/arm/cpu/armv7/omap5/prcm-regs.c
arch/arm/cpu/armv7/virt-v7.c
arch/arm/dts/exynos5250.dtsi
arch/arm/include/asm/arch-at91/at91_common.h
arch/arm/include/asm/arch-at91/atmel_usba_udc.h [new file with mode: 0644]
arch/arm/include/asm/arch-at91/sama5d3.h
arch/arm/include/asm/arch-exynos/clk.h
arch/arm/include/asm/arch-exynos/clock.h
arch/arm/include/asm/arch-exynos/cpu.h
arch/arm/include/asm/arch-exynos/i2s-regs.h
arch/arm/include/asm/arch-exynos/periph.h
arch/arm/include/asm/arch-exynos/spi.h
arch/arm/include/asm/arch-omap5/ehci.h
arch/arm/include/asm/arch-omap5/omap.h
arch/arm/include/asm/arch-omap5/spl.h
arch/arm/include/asm/omap_common.h
arch/powerpc/cpu/mpc85xx/cmd_errata.c
arch/powerpc/cpu/mpc85xx/start.S
arch/powerpc/cpu/ppc4xx/4xx_pci.c
arch/powerpc/cpu/ppc4xx/4xx_uart.c
arch/powerpc/cpu/ppc4xx/miiphy.c
arch/powerpc/cpu/ppc4xx/start.S
arch/powerpc/include/asm/config_mpc85xx.h
arch/powerpc/include/asm/ppc405.h
arch/powerpc/include/asm/ppc440.h
arch/powerpc/include/asm/ppc4xx-emac.h
arch/powerpc/include/asm/ppc4xx-mal.h
arch/powerpc/include/asm/ppc4xx.h
board/RPXlite_dw/README
board/atmel/sama5d3xek/sama5d3xek.c
board/cray/L1/init.S
board/csb272/init.S
board/csb472/init.S
board/esd/pci405/writeibm.S
board/freescale/mx28evk/README
board/jse/init.S
board/keymile/common/common.c
board/keymile/common/ivm.c
board/keymile/km83xx/km83xx.c
board/keymile/scripts/ramfs-common.txt
board/mpl/common/pci.c
board/mpl/mip405/init.S
board/mpl/pip405/init.S
board/samsung/dts/exynos5250-smdk5250.dts
board/samsung/dts/exynos5250-snow.dts
board/sbc8349/README
board/sc3/init.S
board/ti/dra7xx/mux_data.h
board/w7o/init.S
boards.cfg
common/cmd_bootm.c
common/cmd_dfu.c
common/cmd_ext2.c
common/cmd_ext4.c
common/cmd_fat.c
common/cmd_fs.c
common/cmd_gpt.c
common/cmd_mmc.c
common/cmd_mtdparts.c
common/cmd_pxe.c
common/cmd_sf.c
common/cmd_ubi.c
common/cmd_usb_mass_storage.c
common/image-fdt.c
common/image-fit.c
common/image.c
common/spl/spl_mmc.c
disk/part_efi.c
doc/README.JFFS2_NAND
doc/README.hwconfig
doc/README.ubi
doc/SPI/README.ti_qspi_dra_test [new file with mode: 0644]
doc/SPI/README.ti_qspi_flash [new file with mode: 0644]
doc/SPI/status.txt [new file with mode: 0644]
doc/git-mailrc
doc/uImage.FIT/command_syntax_extensions.txt
doc/uImage.FIT/source_file_format.txt
drivers/block/sym53c8xx.c
drivers/dfu/Makefile
drivers/dfu/dfu.c
drivers/dfu/dfu_mmc.c
drivers/dfu/dfu_nand.c
drivers/dfu/dfu_ram.c [new file with mode: 0644]
drivers/mmc/Makefile
drivers/mmc/dw_mmc.c
drivers/mmc/mmc.c
drivers/mmc/mmc_private.h [new file with mode: 0644]
drivers/mmc/mmc_write.c [new file with mode: 0644]
drivers/mmc/omap_hsmmc.c
drivers/mmc/s5p_sdhci.c
drivers/mmc/sdhci.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/nand_base.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/spi/Makefile
drivers/mtd/spi/atmel.c [deleted file]
drivers/mtd/spi/eon.c [deleted file]
drivers/mtd/spi/gigadevice.c [deleted file]
drivers/mtd/spi/macronix.c [deleted file]
drivers/mtd/spi/ramtron.c
drivers/mtd/spi/sf.c [new file with mode: 0644]
drivers/mtd/spi/sf_internal.h [moved from drivers/mtd/spi/spi_flash_internal.h with 62% similarity]
drivers/mtd/spi/sf_ops.c [new file with mode: 0644]
drivers/mtd/spi/sf_probe.c [new file with mode: 0644]
drivers/mtd/spi/spansion.c [deleted file]
drivers/mtd/spi/spi_flash.c [deleted file]
drivers/mtd/spi/sst.c [deleted file]
drivers/mtd/spi/stmicro.c [deleted file]
drivers/mtd/spi/winbond.c [deleted file]
drivers/net/4xx_enet.c
drivers/net/npe/miiphy.c
drivers/net/phy/smsc.c
drivers/pci/pci_auto.c
drivers/power/power_core.c
drivers/sound/max98095.c
drivers/sound/max98095.h
drivers/sound/samsung-i2s.c
drivers/sound/sound.c
drivers/sound/wm8994.c
drivers/sound/wm8994_registers.h
drivers/spi/Makefile
drivers/spi/exynos_spi.c
drivers/spi/mxs_spi.c
drivers/spi/ti_qspi.c [new file with mode: 0644]
drivers/usb/gadget/Makefile
drivers/usb/gadget/atmel_usba_udc.c [new file with mode: 0644]
drivers/usb/gadget/atmel_usba_udc.h [new file with mode: 0644]
drivers/usb/gadget/config.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/f_dfu.h
drivers/usb/gadget/g_dnl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/musb/musb_hcd.c
examples/standalone/README.smc91111_eeprom
fs/fs.c
include/common.h
include/configs/P2041RDB.h
include/configs/am335x_evm.h
include/configs/da850evm.h
include/configs/dra7xx_evm.h
include/configs/eXalion.h
include/configs/km/keymile-common.h
include/configs/km/km83xx-common.h
include/configs/km82xx.h
include/configs/omap5_common.h
include/configs/sacsng.h
include/configs/sama5d3xek.h
include/configs/top9000.h
include/dfu.h
include/fs.h
include/i2s.h
include/jffs2/load_kernel.h
include/libfdt.h
include/linux/fb.h
include/linux/mtd/nand.h
include/linux/usb/atmel_usba_udc.h [new file with mode: 0644]
include/linux/usb/gadget.h
include/miiphy.h
include/mmc.h
include/sdhci.h
include/spi.h
include/spi_flash.h
include/usb_mass_storage.h
lib/hashtable.c
post/board/lwmon5/sysmon.c
tools/buildman/README
tools/buildman/board.py
tools/buildman/bsettings.py
tools/buildman/builder.py
tools/buildman/buildman.py
tools/buildman/test.py
tools/buildman/toolchain.py
tools/checkpatch.pl
tools/fit_image.c

index 41961256a63665425559ea85abd1f2c8d37dcd6b..9f6119255732e9122b3cb4b2d09fb1b2eb38c355 100644 (file)
@@ -52,5 +52,5 @@ GNU Lesser General Public License v2.1 or later       LGPL-2.1+       Y               lgpl-2.1.txt            http:
 eCos license version 2.0                       eCos-2.0                        eCos-2.0.txt            http://www.gnu.org/licenses/ecos-license.html
 BSD 2-Clause License                           BSD-2-Clause    Y               bsd-2-clause.txt        http://spdx.org/licenses/BSD-2-Clause
 BSD 3-clause "New" or "Revised" License                BSD-3-Clause    Y               bsd-3-clause.txt        http://spdx.org/licenses/BSD-3-Clause#licenseText
-IBM PIBS (PowerPC Initialization and           ibm-pibs                        ibm-pibs.txt
+IBM PIBS (PowerPC Initialization and           IBM-pibs                        ibm-pibs.txt
        Boot Software) license
index 7d62f3877c7b9dd09514d5f229c1eaa965de08f5..8a7ed69e658ebd59a47573496c9f2989662d1bb4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 VERSION = 2013
 PATCHLEVEL = 10
 SUBLEVEL =
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc4
 ifneq "$(SUBLEVEL)" ""
 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 else
@@ -45,13 +45,13 @@ endif
 
 #########################################################################
 #
-# U-boot build supports producing a object files to the separate external
+# U-boot build supports generating object files in a separate external
 # directory. Two use cases are supported:
 #
 # 1) Add O= to the make command line
 # 'make O=/tmp/build all'
 #
-# 2) Set environement variable BUILD_DIR to point to the desired location
+# 2) Set environment variable BUILD_DIR to point to the desired location
 # 'export BUILD_DIR=/tmp/build'
 # 'make'
 #
@@ -59,7 +59,7 @@ endif
 # 'export BUILD_DIR=/tmp/build'
 # './MAKEALL'
 #
-# Command line 'O=' setting overrides BUILD_DIR environent variable.
+# Command line 'O=' setting overrides BUILD_DIR environment variable.
 #
 # When none of the above methods is used the local build is performed and
 # the object files are placed in the source directory.
@@ -839,7 +839,7 @@ unconfig:
 
 sinclude $(obj).boards.depend
 $(obj).boards.depend:  boards.cfg
-       @awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE) -d" }' $< > $@
+       @awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE)" }' $< > $@
 
 #
 # Functions to generate common board directory names
diff --git a/README b/README
index 0bb1ad5e405488a3ed081d2ad8542f0ec0766d8c..cee8e2f1646d970bfe8ef8c3727978997e409ca6 100644 (file)
--- a/README
+++ b/README
@@ -151,9 +151,6 @@ Directory Hierarchy:
   /blackfin            Files generic to Analog Devices Blackfin architecture
     /cpu               CPU specific files
     /lib               Architecture specific library files
-  /x86                 Files generic to x86 architecture
-    /cpu               CPU specific files
-    /lib               Architecture specific library files
   /m68k                        Files generic to m68k architecture
     /cpu               CPU specific files
       /mcf52x2         Files specific to Freescale ColdFire MCF52x2 CPUs
@@ -177,6 +174,9 @@ Directory Hierarchy:
   /nios2               Files generic to Altera NIOS2 architecture
     /cpu               CPU specific files
     /lib               Architecture specific library files
+  /openrisc            Files generic to OpenRISC architecture
+    /cpu               CPU specific files
+    /lib               Architecture specific library files
   /powerpc             Files generic to PowerPC architecture
     /cpu               CPU specific files
       /74xx_7xx                Files specific to Freescale MPC74xx and 7xx CPUs
@@ -199,12 +199,16 @@ Directory Hierarchy:
       /leon2           Files specific to Gaisler LEON2 SPARC CPU
       /leon3           Files specific to Gaisler LEON3 SPARC CPU
     /lib               Architecture specific library files
+  /x86                 Files generic to x86 architecture
+    /cpu               CPU specific files
+    /lib               Architecture specific library files
 /api                   Machine/arch independent API for external apps
 /board                 Board dependent files
 /common                        Misc architecture independent functions
 /disk                  Code for disk drive partition handling
 /doc                   Documentation (don't expect too much)
 /drivers               Commonly used device drivers
+/dts                   Contains Makefile for building internal U-Boot fdt.
 /examples              Example code for standalone applications, etc.
 /fs                    Filesystem code (cramfs, ext2, jffs2, etc.)
 /include               Header Files
@@ -214,7 +218,7 @@ Directory Hierarchy:
   /lzo                 Library files to support LZO decompression
 /net                   Networking code
 /post                  Power On Self Test
-/rtc                   Real Time Clock drivers
+/spl                   Secondary Program Loader framework
 /tools                 Tools to build S-Record or U-Boot images, etc.
 
 Software Configuration:
@@ -1403,6 +1407,12 @@ The following options need to be configured:
                CONFIG_DFU_NAND
                This enables support for exposing NAND devices via DFU.
 
+               CONFIG_DFU_RAM
+               This enables support for exposing RAM via DFU.
+               Note: DFU spec refer to non-volatile memory usage, but
+               allow usages beyond the scope of spec - here RAM usage,
+               one that would help mostly the developer.
+
                CONFIG_SYS_DFU_DATA_BUF_SIZE
                Dfu transfer uses a buffer before writing data to the
                raw storage device. Make the size (in bytes) of this buffer
@@ -3358,7 +3368,7 @@ Configuration Settings:
                the Linux kernel; all data that must be processed by
                the Linux kernel (bd_info, boot arguments, FDT blob if
                used) must be put below this limit, unless "bootm_low"
-               enviroment variable is defined and non-zero. In such case
+               environment variable is defined and non-zero. In such case
                all data for the Linux kernel must be between "bootm_low"
                and "bootm_low" + CONFIG_SYS_BOOTMAPSZ.  The environment
                variable "bootm_mapsize" will override the value of
@@ -3471,7 +3481,7 @@ Configuration Settings:
 
 - CONFIG_ENV_FLAGS_LIST_DEFAULT
 - CONFIG_ENV_FLAGS_LIST_STATIC
-       Enable validation of the values given to enviroment variables when
+       Enable validation of the values given to environment variables when
        calling env set.  Variables can be restricted to only decimal,
        hexadecimal, or boolean.  If CONFIG_CMD_NET is also defined,
        the variables can also be restricted to IP address or MAC address.
index 3e21cdb2fdbeb9db533ecf6e3cf3b5b07ed2c4d5..3f3926428919b487c9ab0795bc61df1a2bd202a5 100644 (file)
@@ -28,7 +28,7 @@
  * by u-Boot commands.
  *
  * Note: Redundant environment will not work in this flash since
- * it does use partial page writes. Make sure the environent spans
+ * it does use partial page writes. Make sure the environment spans
  * whole pages!
  */
 
index cde3172fe3c8c2b67742bb17767e86e1a729f34e..d4711c070c3ddaef84740c608d75cb0d6c5617bd 100644 (file)
@@ -302,7 +302,7 @@ int arch_cpu_init(void)
        /*
         * Configures the I/O voltage of the pads connected to Egigabit
         * Ethernet interface to 1.8V
-        * By defult it is set to 3.3V
+        * By default it is set to 3.3V
         */
        reg = readl(KW_REG_MPP_OUT_DRV_REG);
        reg |= (1 << 7);
index e55e1c660255a0e5c9034a5d7a9d4ea283a4cc4b..51f0a6dff118ce1506e154404962943cec45cca2 100644 (file)
@@ -202,3 +202,15 @@ void at91_lcd_hw_init(void)
        at91_periph_clk_enable(ATMEL_ID_LCDC);
 }
 #endif
+
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+void at91_udp_hw_init(void)
+{
+       struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+       /* Enable UPLL clock */
+       writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
+       /* Enable UDPHS clock */
+       at91_periph_clk_enable(ATMEL_ID_UDPHS);
+}
+#endif
index 0cb1a61aa1a0bf49e65cbe98cb8168ec946e4032..36fedd630cde8e924df129bedfb72397f9fd9b11 100644 (file)
@@ -282,6 +282,9 @@ static unsigned long exynos5_get_periph_rate(int peripheral)
                src = readl(&clk->src_peric0);
                div = readl(&clk->div_peric3);
                break;
+       case PERIPH_ID_I2S0:
+               src = readl(&clk->src_mau);
+               div = readl(&clk->div_mau);
        case PERIPH_ID_SPI0:
        case PERIPH_ID_SPI1:
                src = readl(&clk->src_peric1);
@@ -1146,17 +1149,29 @@ int exynos5_set_epll_clk(unsigned long rate)
        return 0;
 }
 
-void exynos5_set_i2s_clk_source(void)
+int exynos5_set_i2s_clk_source(unsigned int i2s_id)
 {
        struct exynos5_clock *clk =
                (struct exynos5_clock *)samsung_get_base_clock();
-
-       clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
-                       (CLK_SRC_SCLK_EPLL));
+       unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
+
+       if (i2s_id == 0) {
+               setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
+               clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
+                               (CLK_SRC_SCLK_EPLL));
+               setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
+       } else if (i2s_id == 1) {
+               clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
+                               (CLK_SRC_SCLK_EPLL));
+       } else {
+               return -1;
+       }
+       return 0;
 }
 
 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
-                                       unsigned int dst_frq)
+                                 unsigned int dst_frq,
+                                 unsigned int i2s_id)
 {
        struct exynos5_clock *clk =
                (struct exynos5_clock *)samsung_get_base_clock();
@@ -1169,13 +1184,27 @@ int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
        }
 
        div = (src_frq / dst_frq);
-       if (div > AUDIO_1_RATIO_MASK) {
-               debug("%s: Frequency ratio is out of range\n", __func__);
-               debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+       if (i2s_id == 0) {
+               if (div > AUDIO_0_RATIO_MASK) {
+                       debug("%s: Frequency ratio is out of range\n",
+                             __func__);
+                       debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+                       return -1;
+               }
+               clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
+                               (div & AUDIO_0_RATIO_MASK));
+       } else if(i2s_id == 1) {
+               if (div > AUDIO_1_RATIO_MASK) {
+                       debug("%s: Frequency ratio is out of range\n",
+                             __func__);
+                       debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+                       return -1;
+               }
+               clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
+                               (div & AUDIO_1_RATIO_MASK));
+       } else {
                return -1;
        }
-       clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
-                               (div & AUDIO_1_RATIO_MASK));
        return 0;
 }
 
@@ -1415,19 +1444,21 @@ int set_spi_clk(int periph_id, unsigned int rate)
                return 0;
 }
 
-int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
+int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
+                         unsigned int i2s_id)
 {
-
        if (cpu_is_exynos5())
-               return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq);
+               return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
        else
                return 0;
 }
 
-void set_i2s_clk_source(void)
+int set_i2s_clk_source(unsigned int i2s_id)
 {
        if (cpu_is_exynos5())
-               exynos5_set_i2s_clk_source();
+               return exynos5_set_i2s_clk_source(i2s_id);
+       else
+               return 0;
 }
 
 int set_epll_clk(unsigned long rate)
index 1b05ebfd7ae9b3cb9a4aca0da1846223cc6d10d9..8002bce79c4e1c7546db53a08d3441b13ed36808 100644 (file)
@@ -220,10 +220,20 @@ static void exynos5_i2s_config(int peripheral)
 {
        int i;
        struct exynos5_gpio_part1 *gpio1 =
-               (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
+               (struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
+       struct exynos5_gpio_part4 *gpio4 =
+               (struct exynos5_gpio_part4 *)samsung_get_base_gpio_part4();
 
-       for (i = 0; i < 5; i++)
-               s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
+       switch (peripheral) {
+       case PERIPH_ID_I2S0:
+               for (i = 0; i < 5; i++)
+                       s5p_gpio_cfg_pin(&gpio4->z, i, GPIO_FUNC(0x02));
+               break;
+       case PERIPH_ID_I2S1:
+               for (i = 0; i < 5; i++)
+                       s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
+               break;
+       }
 }
 
 void exynos5_spi_config(int peripheral)
@@ -296,6 +306,7 @@ static int exynos5_pinmux_config(int peripheral, int flags)
        case PERIPH_ID_I2C7:
                exynos5_i2c_config(peripheral, flags);
                break;
+       case PERIPH_ID_I2S0:
        case PERIPH_ID_I2S1:
                exynos5_i2s_config(peripheral);
                break;
@@ -463,11 +474,11 @@ static int exynos4_pinmux_config(int peripheral, int flags)
 
 int exynos_pinmux_config(int peripheral, int flags)
 {
-       if (cpu_is_exynos5())
+       if (cpu_is_exynos5()) {
                return exynos5_pinmux_config(peripheral, flags);
-       else if (cpu_is_exynos4())
+       } else if (cpu_is_exynos4()) {
                return exynos4_pinmux_config(peripheral, flags);
-       else {
+       else {
                debug("pinmux functionality not supported\n");
                return -1;
        }
index 358348ffa5fcb9543be4de2816cb7330d28e9bde..24b4c18bd452fa155bcd5ed94c755aa05a33efe7 100644 (file)
@@ -3,23 +3,7 @@
  *
  * Copyright (c) 2013  Andre Przywara <andre.przywara@linaro.org>
  *
- * 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
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <config.h>
index fbbc486621a674c8d87b889acd19abfc5e69e574..a1b249e734376253536d24a1bf317010ff952b99 100644 (file)
@@ -170,7 +170,7 @@ static const struct dpll_params per_dpll_params_768mhz_es2[NUM_SYS_CLKS] = {
 
 static const struct dpll_params per_dpll_params_768mhz_dra7xx[NUM_SYS_CLKS] = {
        {32, 0, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1},             /* 12 MHz   */
-       {96, 4, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1},             /* 20 MHz   */
+       {96, 4, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1},              /* 20 MHz   */
        {160, 6, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1},            /* 16.8 MHz */
        {20, 0, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1},             /* 19.2 MHz */
        {192, 12, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1},           /* 26 MHz   */
@@ -426,6 +426,10 @@ void enable_basic_clocks(void)
 #ifdef CONFIG_DRIVER_TI_CPSW
                (*prcm)->cm_gmac_gmac_clkctrl,
 #endif
+
+#ifdef CONFIG_TI_QSPI
+               (*prcm)->cm_l4per_qspi_clkctrl,
+#endif
                0
        };
 
@@ -454,6 +458,10 @@ void enable_basic_clocks(void)
                         clk_modules_explicit_en_essential,
                         1);
 
+#ifdef CONFIG_TI_QSPI
+       setbits_le32((*prcm)->cm_l4per_qspi_clkctrl, (1<<24));
+#endif
+
        /* Enable SCRM OPT clocks for PER and CORE dpll */
        setbits_le32((*prcm)->cm_wkupaon_scrm_clkctrl,
                        OPTFCLKEN_SCRM_PER_MASK);
index 5a3d52c11a26ab7c56ce86b48918715ccfb5de9b..7a7caded030511d1025c3e480efe08f36c841c7b 100644 (file)
@@ -921,6 +921,7 @@ struct prcm_regs const dra7xx_prcm = {
        .cm_l4per_gpio8_clkctrl                 = 0x4a009818,
        .cm_l4per_mmcsd3_clkctrl                = 0x4a009820,
        .cm_l4per_mmcsd4_clkctrl                = 0x4a009828,
+       .cm_l4per_qspi_clkctrl                  = 0x4a009838,
        .cm_l4per_uart1_clkctrl                 = 0x4a009840,
        .cm_l4per_uart2_clkctrl                 = 0x4a009848,
        .cm_l4per_uart3_clkctrl                 = 0x4a009850,
index 6de7fe78135ac51709b2148bab6ba0865aea132e..2cd604f97fa1802462ffa41ddf6bb3e362888d0d 100644 (file)
@@ -1,28 +1,12 @@
 /*
  * (C) Copyright 2013
- * Andre Przywara, Linaro
+ * Andre Przywara, Linaro <andre.przywara@linaro.org>
  *
  * Routines to transition ARMv7 processors from secure into non-secure state
  * and from non-secure SVC into HYP mode
  * needed to enable ARMv7 virtualization for current hypervisors
  *
- * 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
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
index 4fff5e36942ccead7ebf059861ab7204e33eaaa0..1c5474f40b03af1d2b58f01460acb0cd4cdc9b46 100644 (file)
                interrupts = <0 63 0>;
        };
 
+       sound@3830000 {
+               compatible = "samsung,exynos-sound";
+               reg = <0x3830000 0x50>;
+               samsung,i2s-epll-clock-frequency = <192000000>;
+               samsung,i2s-sampling-rate = <48000>;
+               samsung,i2s-bits-per-sample = <16>;
+               samsung,i2s-channels = <2>;
+               samsung,i2s-lr-clk-framesize = <256>;
+               samsung,i2s-bit-clk-framesize = <32>;
+               samsung,i2s-id = <0>;
+       };
+
        sound@12d60000 {
                compatible = "samsung,exynos-sound";
                reg = <0x12d60000 0x20>;
+               samsung,i2s-epll-clock-frequency = <192000000>;
+               samsung,i2s-sampling-rate = <48000>;
+               samsung,i2s-bits-per-sample = <16>;
+               samsung,i2s-channels = <2>;
+               samsung,i2s-lr-clk-framesize = <256>;
+               samsung,i2s-bit-clk-framesize = <32>;
+               samsung,i2s-id = <1>;
        };
 
        spi@12d20000 {
index 9f54fddce51efe63473fbb403f51be20efffdc4e..abcb97d107192ae471f655d2e4315273264a46e4 100644 (file)
@@ -19,6 +19,7 @@ void at91_serial2_hw_init(void);
 void at91_seriald_hw_init(void);
 void at91_spi0_hw_init(unsigned long cs_mask);
 void at91_spi1_hw_init(unsigned long cs_mask);
+void at91_udp_hw_init(void);
 void at91_uhp_hw_init(void);
 void at91_lcd_hw_init(void);
 
diff --git a/arch/arm/include/asm/arch-at91/atmel_usba_udc.h b/arch/arm/include/asm/arch-at91/atmel_usba_udc.h
new file mode 100644 (file)
index 0000000..6f540d2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2005-2013 Atmel Corporation
+ *                        Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __ATMEL_USBA_UDC_H__
+#define __ATMEL_USBA_UDC_H__
+
+#include <linux/usb/atmel_usba_udc.h>
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc)         \
+       [idx] = {                                       \
+               .name   = nam,                          \
+               .index  = idx,                          \
+               .fifo_size      = maxpkt,               \
+               .nr_banks       = maxbk,                \
+               .can_dma        = dma,                  \
+               .can_isoc       = isoc,                 \
+       }
+
+#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \
+       defined(CONFIG_AT91SAM9X5)
+static struct usba_ep_data usba_udc_ep[] = {
+       EP("ep0", 0, 64, 1, 0, 0),
+       EP("ep1", 1, 1024, 2, 1, 1),
+       EP("ep2", 2, 1024, 2, 1, 1),
+       EP("ep3", 3, 1024, 3, 1, 0),
+       EP("ep4", 4, 1024, 3, 1, 0),
+       EP("ep5", 5, 1024, 3, 1, 1),
+       EP("ep6", 6, 1024, 3, 1, 1),
+};
+#elif defined(CONFIG_SAMA5D3)
+static struct usba_ep_data usba_udc_ep[] = {
+       EP("ep0", 0, 64, 1, 0, 0),
+       EP("ep1", 1, 1024, 3, 1, 0),
+       EP("ep2", 2, 1024, 3, 1, 0),
+       EP("ep3", 3, 1024, 2, 1, 0),
+       EP("ep4", 4, 1024, 2, 1, 0),
+       EP("ep5", 5, 1024, 2, 1, 0),
+       EP("ep6", 6, 1024, 2, 1, 0),
+       EP("ep7", 7, 1024, 2, 1, 0),
+       EP("ep8", 8, 1024, 2, 0, 0),
+       EP("ep9", 9, 1024, 2, 0, 0),
+       EP("ep10", 10, 1024, 2, 0, 0),
+       EP("ep11", 11, 1024, 2, 0, 0),
+       EP("ep12", 12, 1024, 2, 0, 0),
+       EP("ep13", 13, 1024, 2, 0, 0),
+       EP("ep14", 14, 1024, 2, 0, 0),
+       EP("ep15", 15, 1024, 2, 0, 0),
+};
+#else
+# error "NO usba_udc_ep defined"
+#endif
+
+#undef EP
+
+struct usba_platform_data pdata = {
+       .num_ep = ARRAY_SIZE(usba_udc_ep),
+       .ep     = usba_udc_ep,
+};
+
+#endif
index fefee5ed259e10fab04de25e5f53c66311b20fc9..123a627ccad7754ed8416911b88304d0505970c8 100644 (file)
 #define ATMEL_BASE_USART3      0xf8024000
 #define ATMEL_BASE_UART1       0xf8028000
 #define ATMEL_BASE_EMAC                0xf802c000
-#define ATMEL_BASE_UDHPS       0xf8030000
+#define ATMEL_BASE_UDPHS       0xf8030000
 #define ATMEL_BASE_SHA         0xf8034000
 #define ATMEL_BASE_AES         0xf8038000
 #define ATMEL_BASE_TDES                0xf803c000
index 71075bd5331ca6d07f72ee46010abdb4ab63f754..1d6fa9370fdd2bef94eb6e7306b7d427679506b0 100644 (file)
@@ -31,8 +31,9 @@ void set_mmc_clk(int dev_index, unsigned int div);
 unsigned long get_lcd_clk(void);
 void set_lcd_clk(void);
 void set_mipi_clk(void);
-void set_i2s_clk_source(void);
-int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
+int set_i2s_clk_source(unsigned int i2s_id);
+int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
+                               unsigned int i2s_id);
 int set_epll_clk(unsigned long rate);
 int set_spi_clk(int periph_id, unsigned int rate);
 
index 2b97b9a042801f99d79e4dcec4420a5de1e94871..cf26eeffcfe4bf08deb8bbfadabd490c5a87f607 100644 (file)
@@ -876,8 +876,12 @@ struct set_epll_con_val {
 #define AUDIO_0_RATIO_MASK             0x0f
 #define AUDIO_1_RATIO_MASK             0x0f
 
+#define AUDIO0_SEL_MASK                        0xf
 #define AUDIO1_SEL_MASK                        0xf
+
 #define CLK_SRC_SCLK_EPLL              0x7
+#define CLK_SRC_MOUT_EPLL              (1<<12)
+#define AUDIO_CLKMUX_ASS               (1<<0)
 
 /* CON0 bit-fields */
 #define EPLL_CON0_MDIV_MASK            0x1ff
index cb924fba8b09e4ede5facab1755bf71a249bd949..4b67191c07e214d25de6bcbe42ab31ff1ae0ed4e 100644 (file)
@@ -50,6 +50,7 @@
 #define EXYNOS4_SPI_ISP_BASE           DEVICE_NOT_AVAILABLE
 #define EXYNOS4_ACE_SFR_BASE           DEVICE_NOT_AVAILABLE
 #define EXYNOS4_DMC_PHY_BASE           DEVICE_NOT_AVAILABLE
+#define EXYNOS4_AUDIOSS_BASE           DEVICE_NOT_AVAILABLE
 
 /* EXYNOS4X12 */
 #define EXYNOS4X12_GPIO_PART3_BASE     0x03860000
 #define EXYNOS4X12_SPI_ISP_BASE                DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_ACE_SFR_BASE                DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_DMC_PHY_BASE                DEVICE_NOT_AVAILABLE
+#define EXYNOS4X12_AUDIOSS_BASE                DEVICE_NOT_AVAILABLE
 
 /* EXYNOS5 Common*/
 #define EXYNOS5_I2C_SPACING            0x10000
 
+#define EXYNOS5_AUDIOSS_BASE           0x03810000
 #define EXYNOS5_GPIO_PART4_BASE                0x03860000
 #define EXYNOS5_PRO_ID                 0x10000000
 #define EXYNOS5_CLOCK_BASE             0x10010000
@@ -226,6 +229,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
 SAMSUNG_BASE(tzpc, TZPC_BASE)
 SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE)
 SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE)
+SAMSUNG_BASE(audio_ass, AUDIOSS_BASE)
 #endif
 
 #endif /* _EXYNOS4_CPU_H */
index 613b9b7a372fb5505f9837f693be7fc8e5e3809d..4a4a7a00b7a2437d5090867b32ede78498a646bf 100644 (file)
@@ -8,10 +8,12 @@
 #ifndef __I2S_REGS_H__
 #define __I2S_REGS_H__
 
+#define CON_RESET              (1 << 31)
 #define CON_TXFIFO_FULL                (1 << 8)
 #define CON_TXCH_PAUSE         (1 << 4)
 #define CON_ACTIVE             (1 << 0)
 
+#define MOD_OP_CLK             (3 << 30)
 #define MOD_BLCP_SHIFT         24
 #define MOD_BLCP_16BIT         (0 << MOD_BLCP_SHIFT)
 #define MOD_BLCP_8BIT          (1 << MOD_BLCP_SHIFT)
@@ -24,6 +26,7 @@
 #define MOD_BLC_MASK           (3 << 13)
 
 #define MOD_SLAVE              (1 << 11)
+#define MOD_RCLKSRC            (0 << 10)
 #define MOD_MASK               (3 << 8)
 #define MOD_LR_LLOW            (0 << 7)
 #define MOD_LR_RLOW            (1 << 7)
@@ -47,4 +50,7 @@
 #define FIC_TXFLUSH            (1 << 15)
 #define FIC_RXFLUSH            (1 << 7)
 
+#define PSREN                  (1 << 15)
+#define PSVAL                  (3 << 8)
+
 #endif /* __I2S_REGS_H__ */
index 9952155986767dbdb15a03d09b14141c2aa26044..64bd8b7c91d1588d37a7bdb3d3a582fab5345fe5 100644 (file)
@@ -34,6 +34,7 @@ enum periph_id {
        PERIPH_ID_SDMMC1,
        PERIPH_ID_SDMMC2,
        PERIPH_ID_SDMMC3,
+       PERIPH_ID_I2S0 = 98,
        PERIPH_ID_I2S1 = 99,
 
        /* Since following peripherals do
index fb23aa69c2a56c3fa66464d70d0da1735de785b3..147c1a7304368932d182ef5f5de288866b8b9636 100644 (file)
@@ -22,7 +22,7 @@ struct exynos_spi {
        unsigned int            rx_data;        /* 0x1c */
        unsigned int            pkt_cnt;        /* 0x20 */
        unsigned char           reserved2[4];
-       unsigned char           reserved3[4];
+       unsigned int            swap_cfg;       /* 0x28 */
        unsigned int            fb_clk;         /* 0x2c */
        unsigned char           padding[0xffd0];
 };
@@ -62,5 +62,14 @@ struct exynos_spi {
 /* Packet Count */
 #define SPI_PACKET_CNT_EN      (1 << 16)
 
+/* Swap config */
+#define SPI_TX_SWAP_EN         (1 << 0)
+#define SPI_TX_BYTE_SWAP       (1 << 2)
+#define SPI_TX_HWORD_SWAP      (1 << 3)
+#define SPI_TX_BYTE_SWAP       (1 << 2)
+#define SPI_RX_SWAP_EN         (1 << 4)
+#define SPI_RX_BYTE_SWAP       (1 << 6)
+#define SPI_RX_HWORD_SWAP      (1 << 7)
+
 #endif /* __ASSEMBLY__ */
 #endif
index 3921e4ab402cea52f18ad8154d8ed2ca72f4b8c6..63aaa020d2326c0eea0fb1f486ec88bf900d207c 100644 (file)
@@ -2,20 +2,7 @@
  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com*
  * Author: Govindraj R <govindraj.raja@ti.com>
  *
- * 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
+ * SPDX-License-Identifier: GPL-2.0+
  */
 
 #ifndef _EHCI_H
index e9a51d340381fbe94bd608e10776db3a2272c455..414d37a5a7e9986adf6c566faaf027b101741027 100644 (file)
@@ -61,6 +61,9 @@
 /* GPMC */
 #define OMAP54XX_GPMC_BASE     0x50000000
 
+/* QSPI */
+#define QSPI_BASE              0x4B300000
+
 /*
  * Hardware Register Details
  */
index fe8b0c01adde5754566d8b3c9dfda9047cbb39e6..57f0de5ffe48c105d410f6bc30bed788317e9f21 100644 (file)
@@ -15,6 +15,7 @@
 #define BOOT_DEVICE_MMC1        5
 #define BOOT_DEVICE_MMC2        6
 #define BOOT_DEVICE_MMC2_2     7
+#define BOOT_DEVICE_SPI                10
 
 #define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC1
 #define MMC_BOOT_DEVICES_END   BOOT_DEVICE_MMC2_2
index 61fee9f06dd3f30c3b6a00deba38ccc94545274d..3a998cc10cf5e9cd3ab8c094b7aed70d1f2bfd2e 100644 (file)
@@ -266,6 +266,7 @@ struct prcm_regs {
        u32 cm_l4per_mmcsd4_clkctrl;
        u32 cm_l4per_msprohg_clkctrl;
        u32 cm_l4per_slimbus2_clkctrl;
+       u32 cm_l4per_qspi_clkctrl;
        u32 cm_l4per_uart1_clkctrl;
        u32 cm_l4per_uart2_clkctrl;
        u32 cm_l4per_uart3_clkctrl;
index eea264b15178f2d11436251ce81957cc74eff7a4..c441bd2f54a3d9447c54458dd7058b85d9cf1aff 100644 (file)
@@ -252,6 +252,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #ifdef CONFIG_SYS_FSL_ERRATUM_A005812
        puts("Work-around for Erratum A-005812 enabled\n");
 #endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A005125
+       puts("Work-around for Erratum A005125 enabled\n");
+#endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447
        if ((SVR_SOC_VER(svr) == SVR_8548 && IS_SVR_REV(svr, 3, 1)) ||
            (SVR_REV(svr) <= CONFIG_SYS_FSL_A004447_SVR_REV))
index ad57a9cfa73453b8b80bd921392415edb2329389..be4f4ae87013547905f9afb9deb93848cfb09106 100644 (file)
@@ -108,6 +108,14 @@ _start_e500:
        isync
 2:
 #endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A005125
+       msync
+       isync
+       mfspr   r3, SPRN_HDBCR0
+       oris    r3, r3, 0x0080
+       mtspr   SPRN_HDBCR0, r3
+#endif
+
 
 #if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC)
        /* ISBC uses L2 as stack.
index 5584e0f3e8e99e748aae32236e7c13f6c1c7ef88..08781a1fb96d6859426d43d849eeec7b87ec8856 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  *
  *  File Name:   405gp_pci.c
  *
index 50c28a0d39f07f682e9a005a101c3ac6ce1eb773..c02058f79bba253ad9cfa6b90155d3f47ac6dfde 100644 (file)
@@ -5,7 +5,7 @@
  * (C) Copyright 2010
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 
 #include <common.h>
index e4a9db6767b674af41b7cb88652678aa59cd27f0..10147de0897d7be956e014ce120759fe55144af3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*-----------------------------------------------------------------------------+
   |
index d9d8cbffaa7a1bcc3ca293b3e87197384c95405e..38bbc5a9bce5676b25ebeae74a251c16dbea9490 100644 (file)
@@ -6,7 +6,7 @@
  *  Copyright (c) 2008 Nuovation System Designs, LLC
  *    Grant Erickson <gerickson@nuovations.com>
  *
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 
 /*
index 15e44de41e66f997ed41f6520f882674f9238469..bec8966fde348613cfbdcbb3a3a8d3c1377f5c17 100644 (file)
@@ -34,6 +34,7 @@
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB  1
 #define CONFIG_SYS_FSL_SEC_COMPAT      2
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_MPC8540)
 #define CONFIG_MAX_CPUS                        1
@@ -52,6 +53,7 @@
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB  0
 #define CONFIG_SYS_FSL_SEC_COMPAT      2
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_MPC8548)
 #define CONFIG_MAX_CPUS                        1
@@ -67,6 +69,7 @@
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
 #define CONFIG_SYS_FSL_RMU
 #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM       2
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV 0x00
 
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
 #define CONFIG_SYS_FSL_RMU
 #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM       2
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_MPC8572)
 #define CONFIG_MAX_CPUS                        2
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_DDR_115
 #define CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1010)
 #define CONFIG_MAX_CPUS                        1
 #define CONFIG_SYS_FSL_ERRATUM_P1010_A003549
 #define CONFIG_SYS_FSL_ERRATUM_SEC_A003571
 #define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV 0x10
 
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P1012 is single core version of P1021 */
 #elif defined(CONFIG_P1012)
 #define QE_MURAM_SIZE                  0x6000UL
 #define MAX_QE_RISC                    1
 #define QE_NUM_OF_SNUM                 28
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P1013 is single core version of P1022 */
 #elif defined(CONFIG_P1013)
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_FSL_SATA_ERRATUM_A001
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1014)
 #define CONFIG_MAX_CPUS                        1
 #define CONFIG_SYS_FM_MURAM_SIZE       0x10000
 #define CONFIG_SYS_FSL_PCIE_COMPAT     "fsl,qoriq-pcie-v2.2"
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff600000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1020)
 #define CONFIG_MAX_CPUS                        2
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1021)
 #define CONFIG_MAX_CPUS                        2
 #define QE_MURAM_SIZE                  0x6000UL
 #define MAX_QE_RISC                    1
 #define QE_NUM_OF_SNUM                 28
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1022)
 #define CONFIG_MAX_CPUS                        2
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_FSL_SATA_ERRATUM_A001
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P1023)
 #define CONFIG_MAX_CPUS                        2
 #define CONFIG_SYS_FM_MURAM_SIZE       0x10000
 #define CONFIG_SYS_FSL_PCIE_COMPAT     "fsl,qoriq-pcie-v2.2"
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff600000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV 0x11
 
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P1025 is lower end variant of P1021 */
 #elif defined(CONFIG_P1025)
 #define QE_MURAM_SIZE                  0x6000UL
 #define MAX_QE_RISC                    1
 #define QE_NUM_OF_SNUM                 28
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 /* P2010 is single core version of P2020 */
 #elif defined(CONFIG_P2010)
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC_A001
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_P2020)
 #define CONFIG_MAX_CPUS                        2
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
 #define CONFIG_SYS_FSL_RMU
 #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM       2
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_PPC_P2041) /* also supports P2040 */
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS1
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_NAND_FSL_IFC
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #elif defined(CONFIG_BSC9132)
 #define CONFIG_MAX_CPUS                        2
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK
 #define CONFIG_SYS_FSL_PCIE_COMPAT     "fsl,qoriq-pcie-v2.2"
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 #define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
 #define CONFIG_SYS_FSL_A004447_SVR_REV 0x11
 
 #define CONFIG_NUM_DDR_CONTROLLERS     1
 #define CONFIG_SYS_FSL_IFC_BANK_COUNT  8
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
+#define CONFIG_SYS_FSL_ERRATUM_A005125
 
 #else
 #error Processor type not defined for this platform
index 8bb342b9295f7be4da390723d8885f789fa93710..f2ed16a216f69c34a554876e827b199933c9acf4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 
 #ifndef        __PPC405_H__
index 0f5bc8d1c79f41fa420be2b7539c75abc365cb50..0cfa88bff592e6f702b3fbe81ea76401b45f3c18 100644 (file)
@@ -9,7 +9,7 @@
  * (C) Copyright 2010
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 
 #ifndef __PPC440_H__
index e6eb332220ef7edab7c9f3cc8d1c7c1e7b6b4fa7..76fa95ca370dfdc49859bfbd04e7f69fb80940b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*----------------------------------------------------------------------------+
 |
index d15290dc1a6ec24329ea1508920649296461bbe7..ef8b174461553cfaacb4a8d7c47af69da868a32b 100644 (file)
@@ -1,6 +1,6 @@
 /* include/mal.h, openbios_walnut, walnut_bios 8/6/99 08:48:40 */
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*----------------------------------------------------------------------------+
 |
index 8d703c663402996644c38cb451142c878821356e..e6a3bff079e4500d905c2840253e321191fec499 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 
 #ifndef        __PPC4XX_H__
index 14296b2ab42a0dd5e06f4694e21fbb915c280942..9e2d0f42a0a41d3e30de429213d9425fc202e76b 100644 (file)
@@ -87,9 +87,9 @@ u-boot>
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-A word on the U-Boot enviroment variable setting and usage :
+A word on the U-Boot environment variable setting and usage :
 
-In the beginning, you could just need very simple defult environment variable setting,
+In the beginning, you could just need very simple default environment variable setting,
 like[include/configs/RPXlite.h] :
 
 #define CONFIG_BOOTCOMMAND                                                      \
index 97caf64d4040fe33e0c00fca362bbdc09ddbac7b..b0965ef211896f20aa12b4233fa72c7a2be35e1d 100644 (file)
 #include <net.h>
 #include <netdev.h>
 
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+#include <asm/arch/atmel_usba_udc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* ------------------------------------------------------------------------- */
@@ -170,6 +174,9 @@ int board_init(void)
 #ifdef CONFIG_CMD_USB
        sama5d3xek_usb_hw_init();
 #endif
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+       at91_udp_hw_init();
+#endif
 #ifdef CONFIG_GENERIC_ATMEL_MCI
        sama5d3xek_mci_hw_init();
 #endif
@@ -220,6 +227,12 @@ int board_eth_init(bd_t *bis)
                rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00);
        if (has_gmac())
                rc = macb_eth_initialize(0, (void *)ATMEL_BASE_GMAC, 0x00);
+#endif
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+       usba_udc_probe(&pdata);
+#ifdef CONFIG_USB_ETH_RNDIS
+       usb_eth_initialize(bis);
+#endif
 #endif
 
        return rc;
index 82f21b08b2aebe20e332ba22601b99ec9946fef5..44c688d1f0436b88f7cc951d529bd2c9b79f2be9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 
 /*----------------------------------------------------------------------------- */
index b1283aa69a72b129151a1fb2ca08a5d8505f044e..5961978c8642b82c86b4aef9e2a22e4eec400c7a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
index f5805b79882a961963d77a202aafefaefc50dd37..1ebc9ead3ae5b762f99ae3aa6603862cd465733e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
index 38acca12bf397cfea773b360448df666f264deb5..03eaf97b78e0e0df2fb0c671b9139898d90544dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*----------------------------------------------------------------------------- */
 /* Function:     ext_bus_cntlr_init */
index 524f3fc494598afcce603d3e10795b2e4c1c53a7..0389a1d86c79d66d0d9c3a40a814890ef4eaf93a 100644 (file)
@@ -29,11 +29,11 @@ Environment Storage
 
 There are two targets for mx28evk:
 
-"make mx28evk_config"          - store enviroment variables into MMC
+"make mx28evk_config"          - store environment variables into MMC
 
 or
 
-"make mx28evk_nand_config"     - store enviroment variables into NAND flash
+"make mx28evk_nand_config"     - store environment variables into NAND flash
 
 Choose the target accordingly.
 
index 7b918b558d0fa565f6645487b262ff86398794db..4e449fef206428eee014085924b3251e61ebee48 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*------------------------------------------------------------------------- */
 /* Function:     ext_bus_cntlr_init */
index 86b81102e991cb17d78ca22df8fe55d0a6251e8f..136b2dee12a2f07caa85fd6ea781b8699691d3a9 100644 (file)
@@ -226,7 +226,7 @@ U_BOOT_CMD(km_setboardid, 1, 0, do_setboardid, "setboardid", "read out bid and "
  *                             application and in the init scripts (?)
  *     return 0 in case of match, 1 if not match or error
  */
-int do_checkboardidhwk(cmd_tbl_t *cmdtp, int flag, int argc,
+static int do_checkboardidhwk(cmd_tbl_t *cmdtp, int flag, int argc,
                        char *const argv[])
 {
        unsigned long ivmbid = 0, ivmhwkey = 0;
@@ -367,7 +367,7 @@ U_BOOT_CMD(km_checkbidhwk, 2, 0, do_checkboardidhwk,
  *  if the testpin of the board is asserted, return 1
  *  *  else return 0
  */
-int do_checktestboot(cmd_tbl_t *cmdtp, int flag, int argc,
+static int do_checktestboot(cmd_tbl_t *cmdtp, int flag, int argc,
                        char *const argv[])
 {
        int testpin = 0;
index aabd3a85b72b56e96c506fca5f688da066377b4a..f0e91bbdfe4f310aae832f1924f2a7094e20fc95 100644 (file)
@@ -10,7 +10,7 @@
 #include <i2c.h>
 #include "common.h"
 
-int ivm_calc_crc(unsigned char *buf, int len)
+static int ivm_calc_crc(unsigned char *buf, int len)
 {
        const unsigned short crc_tab[16] = {
                0x0000, 0xCC01, 0xD801, 0x1400,
@@ -236,7 +236,7 @@ static int ivm_analyze_block2(unsigned char *buf, int len)
        return 0;
 }
 
-int ivm_analyze_eeprom(unsigned char *buf, int len)
+static int ivm_analyze_eeprom(unsigned char *buf, int len)
 {
        unsigned short  val;
        unsigned char   valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
index cd861c9f12568e4db34af7852711a29ce0df7960..0543483d5a91d06e81d04299dcc55f7baa154f7e 100644 (file)
@@ -225,6 +225,11 @@ static struct mv88e_sw_reg extsw_conf[] = {
        { PORT(5), 0x1A, 0xADB1 },
        /* port 6, unused, this port has no phy */
        { PORT(6), PORT_CTRL, PORT_DIS },
+       /*
+        * Errata Fix: 1.9V Output from Internal 1.8V Regulator,
+        * acc . MV-S300889-00D.pdf , clause 4.5
+        */
+       { PORT(5), 0x1A, 0xADB1 },
 };
 #endif
 
@@ -277,7 +282,7 @@ int last_stage_init(void)
        return 0;
 }
 
-int fixed_sdram(void)
+static int fixed_sdram(void)
 {
        immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
        u32 msize = 0;
index 8a8d2875587fc0f7c940c33dd01e1a6cb251148d..502c8631f4f766e55c952e6df12761df2ce51364 100644 (file)
@@ -1,5 +1,5 @@
 addramfs=setenv bootargs "${bootargs} phram.phram=rootfs${boot_bank},${rootfsaddr},${rootfssize}"
-actual_bank=-1
+boot_bank=-1
 altbootcmd=run ${subbootcmds}
 bootcmd=run ${subbootcmds}
 subbootcmds=tftpfdt tftpkernel setrootfsaddr tftpramfs flashargs add_default addpanic addramfs boot
index 6ab263a4d9d4e9532247a360178a3fa2473725e1..cd969cb5182d4e3bb6a9b4dcaf739f2495f18ae0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*
  * Adapted for PIP405 03.07.01
index bf886c05c0b9419c4799225585c6f748c2d76af7..642f17c35b6494bb21db0281e62ef931e5744f2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*-----------------------------------------------------------------------------
  * Function:     ext_bus_cntlr_init
index 9ed27990a1acaf0fad4ffc36c3534f8a974722bc..95fed34fcc948580eb937a92eaa403ae34964625 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*-----------------------------------------------------------------------------
  * Function:     ext_bus_cntlr_init
index 1e94c7f82c5010a5efbb4985fdc0dc223db9ca91..b1bba9662e5bba3ee9d24072b8055936d79092b3 100644 (file)
@@ -36,6 +36,7 @@
                mmc3 = "/mmc@12230000";
                serial0 = "/serial@12C30000";
                console = "/serial@12C30000";
+               i2s = "/sound@3830000";
        };
 
        sromc@12250000 {
                };
        };
 
-       sound@12d60000 {
-               samsung,i2s-epll-clock-frequency = <192000000>;
-               samsung,i2s-sampling-rate = <48000>;
-               samsung,i2s-bits-per-sample = <16>;
-               samsung,i2s-channels = <2>;
-               samsung,i2s-lr-clk-framesize = <256>;
-               samsung,i2s-bit-clk-framesize = <32>;
+       sound@3830000 {
                samsung,codec-type = "wm8994";
        };
 
+       sound@12d60000 {
+               status = "disabled";
+       };
+
        i2c@12c70000 {
                soundcodec@1a {
                        reg = <0x1a>;
index 7832e4edda0b756e224ab223e43652dadc48eafe..9b7e57e43d5aa36d4a47f0ad96b74b2fde18c50c 100644 (file)
@@ -36,6 +36,7 @@
                mmc3 = "/mmc@12230000";
                serial0 = "/serial@12C30000";
                console = "/serial@12C30000";
+               i2s = "/sound@3830000";
        };
 
        i2c4: i2c@12ca0000 {
                };
        };
 
-       sound@12d60000 {
-               samsung,i2s-epll-clock-frequency = <192000000>;
-               samsung,i2s-sampling-rate = <48000>;
-               samsung,i2s-bits-per-sample = <16>;
-               samsung,i2s-channels = <2>;
-               samsung,i2s-lr-clk-framesize = <256>;
-               samsung,i2s-bit-clk-framesize = <32>;
+       sound@3830000 {
                samsung,codec-type = "max98095";
+               codec-enable-gpio = <&gpio 0xb7 0>;
        };
 
+        sound@12d60000 {
+                status = "disabled";
+        };
+
        i2c@12cd0000 {
                soundcodec@22 {
                        reg = <0x22>;
index 2c35919f28c81adc79c4b7bea6b00ff63ac4cad8..e2d60cc5305dd21fbfe16f11ea07aa3b0acc3274 100644 (file)
@@ -50,7 +50,7 @@ is a summary of that information:
     trying to preserve your old environment settings and user flash).
   - Set the start address of the erase/flash process to FF80_0000
   - Set the target RAM required to 64kB.
-  - Select sectors for erasing (see note on enviroment below)
+  - Select sectors for erasing (see note on environment below)
   - Select Erase and Reprogram.
 
 Note that some versions of the register files used with Workbench
index 9921f8fc4f12ba1e17c5260894517f7303af823a..46323d26884dcb39e7fc1c69bd79ace04f20d772 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
index 0a86594c6bb3489922e948efc013858523002665..6965cc57d247e6e13cdb5c5012ddd5d9ae99c218 100644 (file)
@@ -51,5 +51,15 @@ const struct pad_conf_entry core_padconf_array_essential[] = {
        {RGMII0_RXD2, (IEN | M0) },
        {RGMII0_RXD1, (IEN | M0) },
        {RGMII0_RXD0, (IEN | M0) },
+       {GPMC_A13, (IEN | PDIS | M1)},  /* QSPI1_RTCLK */
+       {GPMC_A14, (IEN | PDIS | M1)},  /* QSPI1_D[3] */
+       {GPMC_A15, (IEN | PDIS | M1)},  /* QSPI1_D[2] */
+       {GPMC_A16, (IEN | PDIS | M1)},  /* QSPI1_D[1] */
+       {GPMC_A17, (IEN | PDIS | M1)},  /* QSPI1_D[0] */
+       {GPMC_A18, (M1)},  /* QSPI1_SCLK */
+       {GPMC_A3, (IEN | PDIS | M1)},   /* QSPI1_CS2 */
+       {GPMC_A4, (IEN | PDIS | M1)},   /* QSPI1_CS3 */
+       {GPMC_CS2, (IEN | PTU | PDIS | M1)},    /* QSPI1_CS0 */
+       {GPMC_CS3, (IEN | PTU | PDIS | M1)},    /* QSPI1_CS1*/
 };
 #endif /* _MUX_DATA_DRA7XX_H_ */
index 490411e6ee9b5b2aab06edfaa4b3657500b664de..54eda3299f290a7a8bb9610961ecbd000451cb54 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 #include <config.h>
 #include <asm/ppc4xx.h>
index 7581a4ce328bfb1fb5ae3c46082152d142d52e47..aa2ee642d411948cad91511075a52e4b1bfcf065 100644 (file)
@@ -38,7 +38,7 @@
 # It can be used from a shell:
 #      tools/reformat.py -i -d '-' -s 8 <boards.cfg >boards0.cfg && mv boards0.cfg boards.cfg
 # It can directly be invoked from vim:
-#      :%tools/reformat.py -i -d '-' -s 8
+#      :%!tools/reformat.py -i -d '-' -s 8
 #
 # Status, Arch, CPU:SPLCPU, SoC, Vendor, Board name, Target, Options, Maintainers
 ###########################################################################################################
index b07b0f48b20a9053ecef1d0cf9a3282fba17bd17..166b901d76f3dbb386f1952287b345868f01d3c9 100644 (file)
@@ -558,6 +558,7 @@ static ulong bootm_disable_interrupts(void)
 #ifdef CONFIG_NETCONSOLE
        /* Stop the ethernet stack if NetConsole could have left it up */
        eth_halt();
+       eth_unregister(eth_get_dev());
 #endif
 
 #if defined(CONFIG_CMD_USB)
@@ -799,8 +800,12 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
                BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
-               BOOTM_STATE_LOADOS | BOOTM_STATE_OS_PREP |
-               BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, &images, 1);
+               BOOTM_STATE_LOADOS |
+#if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
+               BOOTM_STATE_OS_CMDLINE |
+#endif
+               BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
+               BOOTM_STATE_OS_GO, &images, 1);
 }
 
 int bootm_maybe_autostart(cmd_tbl_t *cmdtp, const char *cmd)
index 793c42212369a85d11047d7315e0f386e77c0e05..7ce92cec87f4fcb156b2d84ff487cb319635f6a4 100644 (file)
@@ -9,34 +9,20 @@
  */
 
 #include <common.h>
-#include <command.h>
-#include <malloc.h>
 #include <dfu.h>
-#include <asm/errno.h>
 #include <g_dnl.h>
 
 static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       const char *str_env;
        char *s = "dfu";
        int ret, i = 0;
-       char *env_bkp;
 
        if (argc < 3)
                return CMD_RET_USAGE;
 
-       str_env = getenv("dfu_alt_info");
-       if (str_env == NULL) {
-               printf("%s: \"dfu_alt_info\" env variable not defined!\n",
-                      __func__);
-               return CMD_RET_FAILURE;
-       }
-
-       env_bkp = strdup(str_env);
-       ret = dfu_config_entities(env_bkp, argv[1],
-                           (int)simple_strtoul(argv[2], NULL, 10));
+       ret = dfu_init_env_entities(argv[1], simple_strtoul(argv[2], NULL, 10));
        if (ret)
-               return CMD_RET_FAILURE;
+               return ret;
 
        if (argc > 3 && strcmp(argv[3], "list") == 0) {
                dfu_show_entities();
@@ -67,7 +53,6 @@ exit:
        g_dnl_unregister();
 done:
        dfu_free_entities();
-       free(env_bkp);
 
        if (dfu_reset())
                run_command("reset", 0);
index 173191980e93100bca63489ddc6204c15f287856..5a4bcc1a36dbea0a89edd3029f1de0babd318334 100644 (file)
@@ -32,7 +32,7 @@ int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  */
 int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       return do_load(cmdtp, flag, argc, argv, FS_TYPE_EXT, 16);
+       return do_load(cmdtp, flag, argc, argv, FS_TYPE_EXT);
 }
 
 U_BOOT_CMD(
@@ -47,6 +47,5 @@ U_BOOT_CMD(
        "load binary file from a Ext2 filesystem",
        "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
        "    - load binary file 'filename' from 'dev' on 'interface'\n"
-       "      to address 'addr' from ext2 filesystem.\n"
-       "      All numeric parameters are assumed to be hex."
+       "      to address 'addr' from ext2 filesystem."
 );
index 4a27cd97c09d0ae1518a7de8050f8bcb9934f7b6..8289d25b0623468017282393e9127841918fbba5 100644 (file)
@@ -45,7 +45,7 @@
 int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
                                                char *const argv[])
 {
-       return do_load(cmdtp, flag, argc, argv, FS_TYPE_EXT, 16);
+       return do_load(cmdtp, flag, argc, argv, FS_TYPE_EXT);
 }
 
 int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -122,5 +122,4 @@ U_BOOT_CMD(ext4load, 6, 0, do_ext4_load,
           "load binary file from a Ext4 filesystem",
           "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
           "    - load binary file 'filename' from 'dev' on 'interface'\n"
-          "      to address 'addr' from ext4 filesystem.\n"
-          "      All numeric parameters are assumed to be hex.");
+          "      to address 'addr' from ext4 filesystem");
index f6d7affa0d48b011999a32bd499cbcff3be8e823..a12d8fa09830be49f222fc6952cddc45814786ba 100644 (file)
@@ -19,7 +19,7 @@
 
 int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       return do_load(cmdtp, flag, argc, argv, FS_TYPE_FAT, 16);
+       return do_load(cmdtp, flag, argc, argv, FS_TYPE_FAT);
 }
 
 
@@ -35,8 +35,7 @@ U_BOOT_CMD(
        "      the load stops on end of file.\n"
        "      If either 'pos' or 'bytes' are not aligned to\n"
        "      ARCH_DMA_MINALIGN then a misaligned buffer warning will\n"
-       "      be printed and performance will suffer for the load.\n"
-       "      All numeric parameters are assumed to be hex."
+       "      be printed and performance will suffer for the load."
 );
 
 static int do_fat_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
index a681d03d1b1d80d515eb7aa82bdbfbf13ce7b84e..91a205ac1e6994e3c51006c68c3adc164a72e478 100644 (file)
@@ -22,7 +22,7 @@
 
 int do_load_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       return do_load(cmdtp, flag, argc, argv, FS_TYPE_ANY, 0);
+       return do_load(cmdtp, flag, argc, argv, FS_TYPE_ANY);
 }
 
 U_BOOT_CMD(
@@ -34,9 +34,7 @@ U_BOOT_CMD(
        "      'bytes' gives the size to load in bytes.\n"
        "      If 'bytes' is 0 or omitted, the file is read until the end.\n"
        "      'pos' gives the file byte position to start reading from.\n"
-       "      If 'pos' is 0 or omitted, the file is read from the start.\n"
-       "      All numeric parameters are assumed to be decimal,\n"
-       "      unless specified otherwise using a leading \"0x\"."
+       "      If 'pos' is 0 or omitted, the file is read from the start."
 );
 
 int do_ls_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
index 06767aa5e5045f831183c93804f60049da33f626..a46f5cc3431a1b3e386247952aa227db06460622 100644 (file)
@@ -161,7 +161,7 @@ static int set_gpt_info(block_dev_desc_t *dev_desc,
        /* allocate memory for partitions */
        parts = calloc(sizeof(disk_partition_t), p_count);
 
-       /* retrive partions data from string */
+       /* retrieve partitions data from string */
        for (i = 0; i < p_count; i++) {
                tok = strsep(&s, ";");
 
@@ -316,7 +316,7 @@ static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
        "GUID Partition Table",
-       "<command> <interface> <dev> <partions_list>\n"
+       "<command> <interface> <dev> <partitions_list>\n"
        " - GUID partition table restoration\n"
        " Restore GPT information on a device connected\n"
        " to interface\n"
index 1cdeb443fcc5474498832bb1ebf7269b4f54319a..67a94a746882c2c3cafd1c35e7bd295c76ae5b6e 100644 (file)
@@ -260,7 +260,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                                if (!ret)
                                        mmc->part_num = part;
 
-                               printf("switch to partions #%d, %s\n",
+                               printf("switch to partitions #%d, %s\n",
                                                part, (!ret) ? "OK" : "ERROR");
                        }
                }
@@ -421,7 +421,7 @@ U_BOOT_CMD(
        "mmc close <dev> <boot_partition>\n"
        " - Enable boot_part for booting and disable access to boot_part\n"
        "mmc bootpart <device num> <boot part size MB> <RPMB part size MB>\n"
-       " - change sizes of boot and RPMB partions of specified device\n"
+       " - change sizes of boot and RPMB partitions of specified device\n"
 #endif
        );
 #endif /* !CONFIG_GENERIC_MMC */
index 3023479d1d764a9228172dad8a4ccaf0fea1afe4..40b6333ebf4cd15959811273da8617f30b15c360 100644 (file)
 DECLARE_GLOBAL_DATA_PTR;
 
 /* special size referring to all the remaining space in a partition */
-#define SIZE_REMAINING         0xFFFFFFFF
+#define SIZE_REMAINING         (~0llu)
 
 /* special offset value, it is used when not provided by user
  *
  * this value is used temporarily during parsing, later such offests
  * are recalculated */
-#define OFFSET_NOT_SPECIFIED   0xFFFFFFFF
+#define OFFSET_NOT_SPECIFIED   (~0llu)
 
 /* minimum partition size */
 #define MIN_PART_SIZE          4096
@@ -160,9 +160,9 @@ static int device_del(struct mtd_device *dev);
  * @param retptr output pointer to next char after parse completes (output)
  * @return resulting unsigned int
  */
-static unsigned long memsize_parse (const char *const ptr, const char **retptr)
+static u64 memsize_parse (const char *const ptr, const char **retptr)
 {
-       unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
+       u64 ret = simple_strtoull(ptr, (char **)retptr, 0);
 
        switch (**retptr) {
                case 'G':
@@ -193,20 +193,20 @@ static unsigned long memsize_parse (const char *const ptr, const char **retptr)
  * @param buf output buffer
  * @param size size to be converted to string
  */
-static void memsize_format(char *buf, u32 size)
+static void memsize_format(char *buf, u64 size)
 {
 #define SIZE_GB ((u32)1024*1024*1024)
 #define SIZE_MB ((u32)1024*1024)
 #define SIZE_KB ((u32)1024)
 
        if ((size % SIZE_GB) == 0)
-               sprintf(buf, "%ug", size/SIZE_GB);
+               sprintf(buf, "%llug", size/SIZE_GB);
        else if ((size % SIZE_MB) == 0)
-               sprintf(buf, "%um", size/SIZE_MB);
+               sprintf(buf, "%llum", size/SIZE_MB);
        else if (size % SIZE_KB == 0)
-               sprintf(buf, "%uk", size/SIZE_KB);
+               sprintf(buf, "%lluk", size/SIZE_KB);
        else
-               sprintf(buf, "%u", size);
+               sprintf(buf, "%llu", size);
 }
 
 /**
@@ -310,6 +310,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)
        struct mtd_info *mtd = NULL;
        int i, j;
        ulong start;
+       u64 offset, size;
 
        if (get_mtd_info(id->type, id->num, &mtd))
                return 1;
@@ -321,14 +322,16 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)
                 * Only one eraseregion (NAND, OneNAND or uniform NOR),
                 * checking for alignment is easy here
                 */
-               if ((unsigned long)part->offset % mtd->erasesize) {
+               offset = part->offset;
+               if (do_div(offset, mtd->erasesize)) {
                        printf("%s%d: partition (%s) start offset"
                               "alignment incorrect\n",
                               MTD_DEV_TYPE(id->type), id->num, part->name);
                        return 1;
                }
 
-               if (part->size % mtd->erasesize) {
+               size = part->size;
+               if (do_div(size, mtd->erasesize)) {
                        printf("%s%d: partition (%s) size alignment incorrect\n",
                               MTD_DEV_TYPE(id->type), id->num, part->name);
                        return 1;
@@ -381,10 +384,9 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)
 
 
 /**
- * Performs sanity check for supplied partition. Offset and size are verified
- * to be within valid range. Partition type is checked and either
- * parts_validate_nor() or parts_validate_nand() is called with the argument
- * of part.
+ * Performs sanity check for supplied partition. Offset and size are
+ * verified to be within valid range. Partition type is checked and
+ * part_validate_eraseblock() is called with the argument of part.
  *
  * @param id of the parent device
  * @param part partition to validate
@@ -396,7 +398,7 @@ static int part_validate(struct mtdids *id, struct part_info *part)
                part->size = id->size - part->offset;
 
        if (part->offset > id->size) {
-               printf("%s: offset %08x beyond flash size %08x\n",
+               printf("%s: offset %08llx beyond flash size %08llx\n",
                                id->mtd_id, part->offset, id->size);
                return 1;
        }
@@ -420,7 +422,7 @@ static int part_validate(struct mtdids *id, struct part_info *part)
 }
 
 /**
- * Delete selected partition from the partion list of the specified device.
+ * Delete selected partition from the partition list of the specified device.
  *
  * @param dev device to delete partition from
  * @param part partition to delete
@@ -579,8 +581,8 @@ static int part_add(struct mtd_device *dev, struct part_info *part)
 static int part_parse(const char *const partdef, const char **ret, struct part_info **retpart)
 {
        struct part_info *part;
-       unsigned long size;
-       unsigned long offset;
+       u64 size;
+       u64 offset;
        const char *name;
        int name_len;
        unsigned int mask_flags;
@@ -599,7 +601,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
        } else {
                size = memsize_parse(p, &p);
                if (size < MIN_PART_SIZE) {
-                       printf("partition size too small (%lx)\n", size);
+                       printf("partition size too small (%llx)\n", size);
                        return 1;
                }
        }
@@ -671,14 +673,14 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
                part->auto_name = 0;
        } else {
                /* auto generated name in form of size@offset */
-               sprintf(part->name, "0x%08lx@0x%08lx", size, offset);
+               sprintf(part->name, "0x%08llx@0x%08llx", size, offset);
                part->auto_name = 1;
        }
 
        part->name[name_len - 1] = '\0';
        INIT_LIST_HEAD(&part->link);
 
-       debug("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags %d\n",
+       debug("+ partition: name %-22s size 0x%08llx offset 0x%08llx mask flags %d\n",
                        part->name, part->size,
                        part->offset, part->mask_flags);
 
@@ -694,7 +696,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
  * @param size a pointer to the size of the mtd device (output)
  * @return 0 if device is valid, 1 otherwise
  */
-static int mtd_device_validate(u8 type, u8 num, u32 *size)
+static int mtd_device_validate(u8 type, u8 num, u64 *size)
 {
        struct mtd_info *mtd = NULL;
 
@@ -827,7 +829,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_
        LIST_HEAD(tmp_list);
        struct list_head *entry, *n;
        u16 num_parts;
-       u32 offset;
+       u64 offset;
        int err = 1;
 
        debug("===device_parse===\n");
@@ -1072,7 +1074,8 @@ static int generate_mtdparts(char *buf, u32 buflen)
        struct part_info *part, *prev_part;
        char *p = buf;
        char tmpbuf[32];
-       u32 size, offset, len, part_cnt;
+       u64 size, offset;
+       u32 len, part_cnt;
        u32 maxlen = buflen - 1;
 
        debug("--- generate_mtdparts ---\n");
@@ -1271,7 +1274,7 @@ static void print_partition_table(void)
 
                list_for_each(pentry, &dev->parts) {
                        part = list_entry(pentry, struct part_info, link);
-                       printf("%2d: %-20s0x%08x\t0x%08x\t%d\n",
+                       printf("%2d: %-20s0x%08llx\t0x%08llx\t%d\n",
                                        part_num, part->name, part->size,
                                        part->offset, part->mask_flags);
 #endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */
@@ -1298,7 +1301,7 @@ static void list_partitions(void)
        if (current_mtd_dev) {
                part = mtd_part_info(current_mtd_dev, current_mtd_partnum);
                if (part) {
-                       printf("\nactive partition: %s%d,%d - (%s) 0x%08x @ 0x%08x\n",
+                       printf("\nactive partition: %s%d,%d - (%s) 0x%08llx @ 0x%08llx\n",
                                        MTD_DEV_TYPE(current_mtd_dev->id->type),
                                        current_mtd_dev->id->num, current_mtd_partnum,
                                        part->name, part->size, part->offset);
@@ -1398,7 +1401,7 @@ static int delete_partition(const char *id)
 
        if (find_dev_and_part(id, &dev, &pnum, &part) == 0) {
 
-               debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08x@0x%08x\n",
+               debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08llx@0x%08llx\n",
                                MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum,
                                part->name, part->size, part->offset);
 
@@ -1590,7 +1593,7 @@ static int parse_mtdids(const char *const ids)
        struct list_head *entry, *n;
        struct mtdids *id_tmp;
        u8 type, num;
-       u32 size;
+       u64 size;
        int ret = 1;
 
        debug("\n---parse_mtdids---\nmtdids = %s\n\n", ids);
@@ -1664,7 +1667,7 @@ static int parse_mtdids(const char *const ids)
                id->mtd_id[mtd_id_len - 1] = '\0';
                INIT_LIST_HEAD(&id->link);
 
-               debug("+ id %s%d\t%16d bytes\t%s\n",
+               debug("+ id %s%d\t%16lld bytes\t%s\n",
                                MTD_DEV_TYPE(id->type), id->num,
                                id->size, id->mtd_id);
 
index a2fb50ab9d2e93e16d729de5f9f6190737448f06..c5f4a221b8c152770f62601896468d96a12e867f 100644 (file)
@@ -572,7 +572,7 @@ static int label_localboot(struct pxe_label *label)
  * If the label specifies an 'append' line, its contents will overwrite that
  * of the 'bootargs' environment variable.
  */
-static int label_boot(struct pxe_label *label)
+static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
 {
        char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
        char initrd_str[22];
@@ -684,11 +684,11 @@ static int label_boot(struct pxe_label *label)
        if (bootm_argv[3])
                bootm_argc = 4;
 
-       do_bootm(NULL, 0, bootm_argc, bootm_argv);
+       do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
 
 #ifdef CONFIG_CMD_BOOTZ
        /* Try booting a zImage if do_bootm returns */
-       do_bootz(NULL, 0, bootm_argc, bootm_argv);
+       do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
 #endif
        return 1;
 }
@@ -1355,7 +1355,7 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
 /*
  * Try to boot any labels we have yet to attempt to boot.
  */
-static void boot_unattempted_labels(struct pxe_menu *cfg)
+static void boot_unattempted_labels(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
 {
        struct list_head *pos;
        struct pxe_label *label;
@@ -1364,7 +1364,7 @@ static void boot_unattempted_labels(struct pxe_menu *cfg)
                label = list_entry(pos, struct pxe_label, list);
 
                if (!label->attempted)
-                       label_boot(label);
+                       label_boot(cmdtp, label);
        }
 }
 
@@ -1380,7 +1380,7 @@ static void boot_unattempted_labels(struct pxe_menu *cfg)
  * If this function returns, there weren't any labels that successfully
  * booted, or the user interrupted the menu selection via ctrl+c.
  */
-static void handle_pxe_menu(struct pxe_menu *cfg)
+static void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
 {
        void *choice;
        struct menu *m;
@@ -1406,14 +1406,14 @@ static void handle_pxe_menu(struct pxe_menu *cfg)
         */
 
        if (err == 1) {
-               err = label_boot(choice);
+               err = label_boot(cmdtp, choice);
                if (!err)
                        return;
        } else if (err != -ENOENT) {
                return;
        }
 
-       boot_unattempted_labels(cfg);
+       boot_unattempted_labels(cmdtp, cfg);
 }
 
 /*
@@ -1453,7 +1453,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                return 1;
        }
 
-       handle_pxe_menu(cfg);
+       handle_pxe_menu(cmdtp, cfg);
 
        destroy_pxe_menu(cfg);
 
@@ -1559,7 +1559,7 @@ int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        if (prompt)
                cfg->prompt = 1;
 
-       handle_pxe_menu(cfg);
+       handle_pxe_menu(cmdtp, cfg);
 
        destroy_pxe_menu(cfg);
 
index 4af0f0af26bcfa3afbc63708fb019a89cc99d274..3f60979ae78fa9e33d331940db01d6eb25528626 100644 (file)
@@ -152,8 +152,10 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
 {
        debug("offset=%#x, sector_size=%#x, len=%#zx\n",
              offset, flash->sector_size, len);
-       if (spi_flash_read(flash, offset, len, cmp_buf))
+       /* Read the entire sector so to allow for rewriting */
+       if (spi_flash_read(flash, offset, flash->sector_size, cmp_buf))
                return "read";
+       /* Compare only what is meaningful (len) */
        if (memcmp(cmp_buf, buf, len) == 0) {
                debug("Skip region %x size %zx: no change\n",
                      offset, len);
@@ -163,8 +165,17 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
        /* Erase the entire sector */
        if (spi_flash_erase(flash, offset, flash->sector_size))
                return "erase";
+       /* Write the initial part of the block from the source */
        if (spi_flash_write(flash, offset, len, buf))
                return "write";
+       /* If it's a partial sector, rewrite the existing part */
+       if (len != flash->sector_size) {
+               /* Rewrite the original data to the end of the sector */
+               if (spi_flash_write(flash, offset + len,
+                                   flash->sector_size - len, &cmp_buf[len]))
+                       return "write";
+       }
+
        return NULL;
 }
 
index 5ba4feb485bd40faaa9a474588006abdd0e50eb5..122ba7e171c1da4b9238bb3db2e967a156b39d95 100644 (file)
@@ -167,7 +167,7 @@ bad:
        return err;
 }
 
-static int ubi_create_vol(char *volume, int size, int dynamic)
+static int ubi_create_vol(char *volume, int64_t size, int dynamic)
 {
        struct ubi_mkvol_req req;
        int err;
@@ -191,7 +191,7 @@ static int ubi_create_vol(char *volume, int size, int dynamic)
                printf("verify_mkvol_req failed %d\n", err);
                return err;
        }
-       printf("Creating %s volume %s of size %d\n",
+       printf("Creating %s volume %s of size %lld\n",
                dynamic ? "dynamic" : "static", volume, size);
        /* Call real ubi create volume */
        return ubi_create_volume(ubi, &req);
@@ -266,28 +266,15 @@ out_err:
        return err;
 }
 
-int ubi_volume_write(char *volume, void *buf, size_t size)
+int ubi_volume_continue_write(char *volume, void *buf, size_t size)
 {
        int err = 1;
-       int rsvd_bytes = 0;
        struct ubi_volume *vol;
 
        vol = ubi_find_volume(volume);
        if (vol == NULL)
                return ENODEV;
 
-       rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
-       if (size < 0 || size > rsvd_bytes) {
-               printf("size > volume size! Aborting!\n");
-               return EINVAL;
-       }
-
-       err = ubi_start_update(ubi, vol, size);
-       if (err < 0) {
-               printf("Cannot start volume update\n");
-               return -err;
-       }
-
        err = ubi_more_update_data(ubi, vol, buf, size);
        if (err < 0) {
                printf("Couldnt or partially wrote data\n");
@@ -314,6 +301,37 @@ int ubi_volume_write(char *volume, void *buf, size_t size)
        return 0;
 }
 
+int ubi_volume_begin_write(char *volume, void *buf, size_t size,
+       size_t full_size)
+{
+       int err = 1;
+       int rsvd_bytes = 0;
+       struct ubi_volume *vol;
+
+       vol = ubi_find_volume(volume);
+       if (vol == NULL)
+               return ENODEV;
+
+       rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
+       if (size < 0 || size > rsvd_bytes) {
+               printf("size > volume size! Aborting!\n");
+               return EINVAL;
+       }
+
+       err = ubi_start_update(ubi, vol, full_size);
+       if (err < 0) {
+               printf("Cannot start volume update\n");
+               return -err;
+       }
+
+       return ubi_volume_continue_write(volume, buf, size);
+}
+
+int ubi_volume_write(char *volume, void *buf, size_t size)
+{
+       return ubi_volume_begin_write(volume, buf, size, size);
+}
+
 int ubi_volume_read(char *volume, char *buf, size_t size)
 {
        int err, lnum, off, len, tbuf_size;
@@ -498,7 +516,7 @@ int ubi_part(char *part_name, const char *vid_header_offset)
 
 static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       size_t size = 0;
+       int64_t size = 0;
        ulong addr = 0;
 
        if (argc < 2)
@@ -558,13 +576,13 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                }
                /* E.g., create volume size */
                if (argc == 4) {
-                       size = simple_strtoul(argv[3], NULL, 16);
+                       size = simple_strtoull(argv[3], NULL, 16);
                        argc--;
                }
                /* Use maximum available size */
                if (!size) {
-                       size = ubi->avail_pebs * ubi->leb_size;
-                       printf("No size specified -> Using max size (%u)\n", size);
+                       size = (int64_t)ubi->avail_pebs * ubi->leb_size;
+                       printf("No size specified -> Using max size (%lld)\n", size);
                }
                /* E.g., create volume */
                if (argc == 3)
@@ -588,9 +606,22 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                addr = simple_strtoul(argv[2], NULL, 16);
                size = simple_strtoul(argv[4], NULL, 16);
 
-               ret = ubi_volume_write(argv[3], (void *)addr, size);
+               if (strlen(argv[1]) == 10 &&
+                   strncmp(argv[1] + 5, ".part", 5) == 0) {
+                       if (argc < 6) {
+                               ret = ubi_volume_continue_write(argv[3],
+                                               (void *)addr, size);
+                       } else {
+                               size_t full_size;
+                               full_size = simple_strtoul(argv[5], NULL, 16);
+                               ret = ubi_volume_begin_write(argv[3],
+                                               (void *)addr, size, full_size);
+                       }
+               } else {
+                       ret = ubi_volume_write(argv[3], (void *)addr, size);
+               }
                if (!ret) {
-                       printf("%d bytes written to volume %s\n", size,
+                       printf("%lld bytes written to volume %s\n", size,
                               argv[3]);
                }
 
@@ -613,7 +644,7 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                }
 
                if (argc == 3) {
-                       printf("Read %d bytes from volume %s to %lx\n", size,
+                       printf("Read %lld bytes from volume %s to %lx\n", size,
                               argv[3], addr);
 
                        return ubi_volume_read(argv[3], (char *)addr, size);
@@ -636,6 +667,8 @@ U_BOOT_CMD(
                " - create volume name with size\n"
        "ubi write[vol] address volume size"
                " - Write volume from address with size\n"
+       "ubi write.part address volume size [fullsize]\n"
+               " - Write part of a volume from address\n"
        "ubi read[vol] address volume [size]"
                " - Read volume to address with size\n"
        "ubi remove[vol] volume"
index 33a47150055fd9cae8725996dba3e0507e8c578c..ccf7195946e19491edb931d84cd4b159921112dc 100644 (file)
@@ -5,7 +5,6 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <errno.h>
 #include <common.h>
 #include <command.h>
 #include <g_dnl.h>
index 2e22cca54e15d00d2d1aa804c63bb46b7cf68701..6f9ce7d37c227f81f15f0127fe5f1c6d9c8c3566 100644 (file)
@@ -55,7 +55,7 @@ static const image_header_t *image_get_fdt(ulong fdt_addr)
                fdt_error("uImage is compressed");
                return NULL;
        }
-       if (fdt_check_header((char *)image_get_data(fdt_hdr)) != 0) {
+       if (fdt_check_header((void *)image_get_data(fdt_hdr)) != 0) {
                fdt_error("uImage data is not a fdt");
                return NULL;
        }
index 199b4ed16a1e0c36e6f98f943a9b2812a4a7dfc3..cf4b67e3e832dfbe29acfabb15a53e3248b81c47 100644 (file)
@@ -58,7 +58,7 @@ static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
  * @conf_name double pointer to a char, will hold pointer to a configuration
  * unit name
  *
- * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
+ * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
  * where <addr> is a FIT image address that contains configuration
  * with a <conf> unit name.
  *
@@ -84,7 +84,7 @@ int fit_parse_conf(const char *spec, ulong addr_curr,
  * subimage
  * @image_name: double pointer to a char, will hold pointer to a subimage name
  *
- * fit_parse_subimage() expects subimage spec in the for of
+ * fit_parse_subimage() expects subimage spec in the form of
  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
  * subimage with a <subimg> unit name.
  *
@@ -1331,7 +1331,7 @@ int fit_conf_find_compat(const void *fit, const void *fdt)
  *
  * When NULL is provided in second argument fit_conf_get_node() will search
  * for a default configuration node instead. Default configuration node unit
- * name is retrived from FIT_DEFAULT_PROP property of the '/configurations'
+ * name is retrieved from FIT_DEFAULT_PROP property of the '/configurations'
  * node.
  *
  * returns:
@@ -1596,7 +1596,7 @@ int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
        len = (ulong)size;
 
        /* verify that image data is a proper FDT blob */
-       if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) {
+       if (image_type == IH_TYPE_FLATDT && fdt_check_header(buf)) {
                puts("Subimage data is not a FDT");
                return -ENOEXEC;
        }
index 2c88091e6de1be3f02d29304eedf5368368482dd..b0ae58ff3e8cbaf3b82aaa04c3c63d2303e91795 100644 (file)
@@ -652,17 +652,13 @@ int genimg_get_format(const void *img_addr)
 {
        ulong format = IMAGE_FORMAT_INVALID;
        const image_header_t *hdr;
-#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
-       char *fit_hdr;
-#endif
 
        hdr = (const image_header_t *)img_addr;
        if (image_check_magic(hdr))
                format = IMAGE_FORMAT_LEGACY;
 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
        else {
-               fit_hdr = (char *)img_addr;
-               if (fdt_check_header(fit_hdr) == 0)
+               if (fdt_check_header(img_addr) == 0)
                        format = IMAGE_FORMAT_FIT;
        }
 #endif
@@ -965,7 +961,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
  * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
  *      end address (after possible relocation)
  *
- * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
+ * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
  * variable and if requested ramdisk data is moved to a specified location.
  *
  * Initrd_start and initrd_end are set to final (after relocation) ramdisk
index f27b4c277b645ed0555a6df27fb3e04d9e9a240b..fc2f2260f888a308d26d7a63fb5db6e5b95b78df 100644 (file)
@@ -9,7 +9,6 @@
 #include <common.h>
 #include <spl.h>
 #include <asm/u-boot.h>
-#include <asm/utils.h>
 #include <mmc.h>
 #include <fat.h>
 #include <version.h>
@@ -45,8 +44,10 @@ static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector)
                                        (void *)spl_image.load_addr);
 
 end:
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
        if (err == 0)
                printf("spl: mmc blk read err - %lu\n", err);
+#endif
 
        return (err == 0);
 }
@@ -58,7 +59,9 @@ static int mmc_load_image_raw_os(struct mmc *mmc)
                                       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
                                       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
                                       (void *)CONFIG_SYS_SPL_ARGS_ADDR)) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                printf("mmc args blk read error\n");
+#endif
                return -1;
        }
 
@@ -84,9 +87,11 @@ static int mmc_load_image_fat(struct mmc *mmc, const char *filename)
        err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
 
 end:
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
        if (err <= 0)
                printf("spl: error reading image %s, err - %d\n",
                       filename, err);
+#endif
 
        return (err <= 0);
 }
@@ -99,8 +104,10 @@ static int mmc_load_image_fat_os(struct mmc *mmc)
        err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME,
                            (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
        if (err <= 0) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                printf("spl: error reading image %s, err - %d\n",
                       CONFIG_SPL_FAT_LOAD_ARGS_NAME, err);
+#endif
                return -1;
        }
 
@@ -120,13 +127,17 @@ void spl_mmc_load_image(void)
        /* We register only one device. So, the dev id is always 0 */
        mmc = find_mmc_device(0);
        if (!mmc) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                puts("spl: mmc device not found!!\n");
+#endif
                hang();
        }
 
        err = mmc_init(mmc);
        if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                printf("spl: mmc init failed: err - %d\n", err);
+#endif
                hang();
        }
 
@@ -145,7 +156,9 @@ void spl_mmc_load_image(void)
                err = fat_register_device(&mmc->block_dev,
                                          CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
                if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                        printf("spl: fat register err - %d\n", err);
+#endif
                        hang();
                }
 
@@ -155,7 +168,9 @@ void spl_mmc_load_image(void)
                err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
 #endif
        } else {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                puts("spl: wrong MMC boot mode\n");
+#endif
                hang();
        }
 
index b7524d68ba05b570e2286aeb208e2e15ab030f38..9c33ae7a3174b37854ac5368628cf09e9e379bf0 100644 (file)
@@ -164,8 +164,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 
        if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
            !is_pte_valid(&gpt_pte[part - 1])) {
-               printf("%s: *** ERROR: Invalid partition number %d ***\n",
+               debug("%s: *** ERROR: Invalid partition number %d ***\n",
                        __func__, part);
+               free(gpt_pte);
                return -1;
        }
 
index 5018ae8342597f16f58c02c04355282b13703d65..09788d5348110d0b6adada7cce08f59363e21ab8 100644 (file)
@@ -1,6 +1,6 @@
 JFFS2 NAND support:
 
-To ebable, use the following #define in the board configuration file:
+To enable, use the following #define in the board configuration file:
 
 #define CONFIG_JFFS2_NAND 1
 
index cf549651c710f09158a7adf525d85254d8d40d33..b6ddb438cfa78917249fbc4f255262bc5a05a46c 100644 (file)
@@ -18,7 +18,7 @@ Current implementation details/limitations:
    U-Boot. But I haven't bothered yet.
 
 2. Since we don't implement a hwconfig command, i.e. we're working
-   with the environement directly, there is no way to tell that
+   with the environment directly, there is no way to tell that
    toggling a particular option will need a reboot to take
    effect. So, for now it's advised to always reboot the
    target after modifying the hwconfig variable.
index 3cf4ef232d3883b5451ec992c543689f3f24ccab..d82c75c848401adef8b40033f01dcd6652519825 100644 (file)
@@ -14,6 +14,8 @@ ubi part [part] [offset]
 ubi info [l[ayout]] - Display volume and ubi layout information
 ubi create[vol] volume [size] [type] - create volume name with size
 ubi write[vol] address volume size - Write volume from address with size
+ubi write.part address volume size [fullsize]
+ - Write part of a volume from address
 ubi read[vol] address volume [size] - Read volume to address with size
 ubi remove[vol] volume - Remove volume
 [Legends]
@@ -77,6 +79,7 @@ ubi createvol Create UBI volume on UBI device
 ubi removevol  Remove UBI volume from UBI device
 ubi read       Read data from UBI volume to memory
 ubi write      Write data from memory to UBI volume
+ubi write.part Write data from memory to UBI volume, in parts
 
 
 Here a few examples on the usage:
diff --git a/doc/SPI/README.ti_qspi_dra_test b/doc/SPI/README.ti_qspi_dra_test
new file mode 100644 (file)
index 0000000..fe37857
--- /dev/null
@@ -0,0 +1,48 @@
+-------------------------------------------------
+   Simple steps used to test the QSPI at U-Boot
+-------------------------------------------------
+
+For #1, build the patched U-Boot and load MLO/u-boot.img
+
+----------------------------------
+Boot from another medium like MMC
+----------------------------------
+
+U-Boot# mmc dev 0
+mmc0 is current device
+U-Boot# fatload mmc 0 0x82000000 MLO
+reading MLO
+55872 bytes read in 8 ms (6.7 MiB/s)
+U-Boot# fatload mmc 0 0x83000000 u-boot.img
+reading u-boot.img
+248600 bytes read in 19 ms (12.5 MiB/s)
+
+--------------------------------------------------
+Commands to erase/write u-boot/mlo to flash device
+--------------------------------------------------
+U-Boot# sf probe 0
+SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB, mapped at 5c000000
+SF: Warning - Only lower 16MiB accessible, Full access #define CONFIG_SPI_FLASH_BAR
+U-Boot# sf erase 0 0x10000
+SF: 65536 bytes @ 0x0 Erased: OK
+U-Boot# sf erase 0x20000 0x10000
+SF: 65536 bytes @ 0x20000 Erased: OK
+U-Boot# sf erase 0x30000 0x10000
+SF: 65536 bytes @ 0x30000 Erased: OK
+U-Boot# sf erase 0x40000 0x10000
+SF: 65536 bytes @ 0x40000 Erased: OK
+U-Boot# sf erase 0x50000 0x10000
+SF: 65536 bytes @ 0x50000 Erased: OK
+U-Boot# sf erase 0x60000 0x10000
+SF: 65536 bytes @ 0x60000 Erased: OK
+U-Boot# sf write 82000000 0 0x10000
+SF: 65536 bytes @ 0x0 Written: OK
+U-Boot# sf write 83000000 0x20000 0x60000
+SF: 393216 bytes @ 0x20000 Written: OK
+
+For #2, set sysboot to QSPI-1 boot mode(SYSBOOT[5:0] = 100110) and power
+on. ROM should find the GP header at offset 0 and load/execute SPL. SPL
+then detects that ROM was in QSPI-1 mode (boot code 10) and attempts to
+find a U-Boot image header at offset 0x20000 (set in the config file)
+and proceeds to load that image using the U-Boot image payload offset/size
+from the header. It will then start U-Boot.
diff --git a/doc/SPI/README.ti_qspi_flash b/doc/SPI/README.ti_qspi_flash
new file mode 100644 (file)
index 0000000..1b86d01
--- /dev/null
@@ -0,0 +1,47 @@
+QSPI U-boot support
+------------------
+
+Host processor is connected to serial flash device via qpsi
+interface. QSPI is a kind of spi module that allows single,
+dual and quad read access to external spi devices. The module
+has a memory mapped interface which provide direct interface
+for accessing data form external spi devices.
+
+The one QSPI in the device is primarily intended for fast booting
+from Quad SPI flash devices.
+
+Usecase
+-------
+
+MLO/u-boot.img will be flashed from SD/MMC to the flash device
+using serial flash erase and write commands. Then, switch settings
+will be changed to qspi boot. Then, the ROM code will read MLO
+from the predefined location in the flash, where it was flashed and
+execute it after storing it in SDRAM. Then, the MLO will read
+u-boot.img from flash and execute it from SDRAM.
+
+SPI mode
+-------
+SPI mode uses mtd spi framework for transfer and reception of data.
+Can be used in:
+1. Normal mode: use single pin for transfers
+2. Dual Mode: use two pins for transfers.
+3. Quad mode: use four pin for transfer
+
+Memory mapped read mode
+-----------------------
+In this, SPI controller is configured using configuration port and then
+controler is switched to memory mapped port for data read.
+
+Driver
+------
+drivers/qspi/ti_qspi.c
+    - Newly created file which is responsible for configuring the
+       qspi controller and also for providing the low level api which
+       is responsible for transferring the datas from host controller
+       to flash device and vice versa.
+
+Testing
+-------
+A seperated file named README.dra_qspi_test has been created which gives all the
+details about the commands required to test qspi at u-boot level.
diff --git a/doc/SPI/status.txt b/doc/SPI/status.txt
new file mode 100644 (file)
index 0000000..62c3c85
--- /dev/null
@@ -0,0 +1,31 @@
+Status on SPI subsystem:
+=======================
+
+SPI COMMAND (common/cmd_sf, cmd_spi):
+-
+
+SPI FLASH (drivers/mtd/spi):
+- sf_probe.c: SPI flash probing code.
+- sf_ops.c: SPI flash operations code.
+- sf.c: SPI flash interface, which interacts controller driver.
+- Bank Address Register (Accessing flashes > 16Mbytes in 3-byte addressing)
+- Added memory_mapped support for read operations.
+- Common probe support for all supported flash vendors except, ramtron.
+
+SPI DRIVERS (drivers/spi):
+-
+
+TODO:
+- Runtime detection of spi_flash params, SFDP(if possible)
+- Add support for multibus build/accessing.
+- Extended read commands support(dual read, dual IO read)
+- Quad Page Program support.
+- Quad Read support(quad fast read, quad IO read)
+- Dual flash connection topology support(accessing two spi flash memories with single cs)
+- Banking support on dual flash connection topology.
+- Need proper cleanups on spi_flash and drivers.
+
+--
+Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
+18-09-2013.
+07-10-2013.
index 2cacaa034145fe8f0311c641a78a548dba0e4584..251586e05277ed7f715446c0c11889832d62c603 100644 (file)
@@ -18,6 +18,7 @@ alias galak          Kumar Gala <galak@kernel.crashing.org>
 alias gruss          Graeme Russ <graeme.russ@gmail.com>
 alias hs             Heiko Schocher <hs@denx.de>
 alias iwamatsu       Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+alias jagan         Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
 alias jasonjin       Jason Jin <jason.jin@freescale.com>
 alias jhersh         Joe Hershberger <joe.hershberger@gmail.com>
 alias kimphill       Kim Phillips <kim.phillips@freescale.com>
@@ -106,5 +107,6 @@ alias i2c            uboot, hs
 alias mmc            uboot, panto
 alias nand           uboot, scottwood
 alias net            uboot, jhersh
+alias spi           uboot, jagan
 alias usb            uboot, marex
 alias video          uboot, ag
index 002818c226b8e15d714e87b788d4bba8396575f6..6c99b1c1594432a0e4622819ccd3f5bb23edc346 100644 (file)
@@ -170,7 +170,7 @@ bootm 200000
 
 In case of the new uImage argument syntax, the address portion of any argument
 can be omitted. If <addr3> is omitted, then it is assumed that image at
-<addr2> should be used. Similarly, when <addr2> is omitted, is is assumed that
+<addr2> should be used. Similarly, when <addr2> is omitted, it is assumed that
 image at <addr1> should be used. If <addr1> is omitted, it is assumed that the
 current image address is to be used. For example, consider the following
 commands:
index 6d2070758de82111c79d41383e6e4f70328d0f16..160b2d05f882342b14c820951e7e8c06f8b4594e 100644 (file)
@@ -62,7 +62,7 @@ c) Image building procedure
 The following picture shows how the new uImage is prepared. Input consists of
 image source file (.its) and a set of data files. Image is created with the
 help of standard U-boot mkimage tool which in turn uses dtc (device tree
-compiler) to produce image tree blob (.itb).  Resulting .itb file is is the
+compiler) to produce image tree blob (.itb).  Resulting .itb file is the
 actual binary of a new uImage.
 
 
index c538e370e1e5a4356d9bd06671e0b63c1def84a9..6f1ac857230ef93cf78e6b17e472d58eb6493eef 100644 (file)
@@ -248,7 +248,7 @@ void scsi_print_error (ccb * pccb)
 
 /******************************************************************************
  * sets-up the SCSI controller
- * the base memory address is retrived via the pci_read_config_dword
+ * the base memory address is retrieved via the pci_read_config_dword
  */
 void scsi_low_level_init(int busdevfunc)
 {
index fca370ae04c05f24730b200f38f446b004eb4ec0..de9e44e1ef1c5635febf33f091362c5d5f792f65 100644 (file)
@@ -12,6 +12,7 @@ LIB   = $(obj)libdfu.o
 COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o
 COBJS-$(CONFIG_DFU_MMC) += dfu_mmc.o
 COBJS-$(CONFIG_DFU_NAND) += dfu_nand.o
+COBJS-$(CONFIG_DFU_RAM) += dfu_ram.o
 
 SRCS    := $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
index d73d5103919662e8a8c044be35922e4bed33dec4..56b21c78abc68676710eb90f003bb26bead26ea4 100644 (file)
@@ -41,6 +41,29 @@ static int dfu_find_alt_num(const char *s)
        return ++i;
 }
 
+int dfu_init_env_entities(char *interface, int dev)
+{
+       const char *str_env;
+       char *env_bkp;
+       int ret;
+
+       str_env = getenv("dfu_alt_info");
+       if (!str_env) {
+               error("\"dfu_alt_info\" env variable not defined!\n");
+               return -EINVAL;
+       }
+
+       env_bkp = strdup(str_env);
+       ret = dfu_config_entities(env_bkp, interface, dev);
+       if (ret) {
+               error("DFU entities configuration failed!\n");
+               return ret;
+       }
+
+       free(env_bkp);
+       return 0;
+}
+
 static unsigned char *dfu_buf;
 static unsigned long dfu_buf_size = CONFIG_SYS_DFU_DATA_BUF_SIZE;
 
@@ -153,8 +176,8 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 
        /* we should be in buffer now (if not then size too large) */
        if ((dfu->i_buf + size) > dfu->i_buf_end) {
-               printf("%s: Wrong size! [%d] [%d] - %d\n",
-                      __func__, dfu->i_blk_seq_num, blk_seq_num, size);
+               error("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf,
+                     size, dfu->i_buf_end);
                return -1;
        }
 
@@ -325,6 +348,9 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
        } else if (strcmp(interface, "nand") == 0) {
                if (dfu_fill_entity_nand(dfu, s))
                        return -1;
+       } else if (strcmp(interface, "ram") == 0) {
+               if (dfu_fill_entity_ram(dfu, s))
+                       return -1;
        } else {
                printf("%s: Device %s not (yet) supported!\n",
                       __func__,  interface);
@@ -374,14 +400,14 @@ int dfu_config_entities(char *env, char *interface, int num)
 
 const char *dfu_get_dev_type(enum dfu_device_type t)
 {
-       const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND" };
+       const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM" };
        return dev_t[t];
 }
 
 const char *dfu_get_layout(enum dfu_layout l)
 {
        const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
-                                          "EXT3", "EXT4" };
+                                          "EXT3", "EXT4", "RAM_ADDR" };
        return dfu_layout[l];
 }
 
index 0871a770b7b1d9b9bfc8c23a02701766345d76a1..f942758696e326843368847d0ef947b8be41d32b 100644 (file)
 #include <div64.h>
 #include <dfu.h>
 
-enum dfu_mmc_op {
-       DFU_OP_READ = 1,
-       DFU_OP_WRITE,
-};
-
 static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE)
                                dfu_file_buf[CONFIG_SYS_DFU_MAX_FILE_SIZE];
 static long dfu_file_buf_len;
 
-static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
+static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
                        u64 offset, void *buf, long *len)
 {
        char cmd_buf[DFU_CMD_BUF_SIZE];
@@ -65,7 +60,7 @@ static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len)
        return 0;
 }
 
-static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
+static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
                        void *buf, long *len)
 {
        char cmd_buf[DFU_CMD_BUF_SIZE];
index 0ec12cff264fe8ad88117f8fe8748851cf0d4e85..edbf5a97b9001a84cd93570884f6aee5372cdc96 100644 (file)
 #include <jffs2/load_kernel.h>
 #include <nand.h>
 
-enum dfu_nand_op {
-       DFU_OP_READ = 1,
-       DFU_OP_WRITE,
-};
-
-static int nand_block_op(enum dfu_nand_op op, struct dfu_entity *dfu,
+static int nand_block_op(enum dfu_op op, struct dfu_entity *dfu,
                        u64 offset, void *buf, long *len)
 {
        loff_t start, lim;
diff --git a/drivers/dfu/dfu_ram.c b/drivers/dfu/dfu_ram.c
new file mode 100644 (file)
index 0000000..335a8e1
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2013
+ * Afzal Mohammed <afzal.mohd.ma@gmail.com>
+ *
+ * Reference: dfu_mmc.c
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dfu.h>
+
+static int dfu_transfer_medium_ram(enum dfu_op op, struct dfu_entity *dfu,
+                                  u64 offset, void *buf, long *len)
+{
+       if (dfu->layout != DFU_RAM_ADDR) {
+               error("unsupported layout: %s\n", dfu_get_layout(dfu->layout));
+               return  -EINVAL;
+       }
+
+       if (offset > dfu->data.ram.size) {
+               error("request exceeds allowed area\n");
+               return -EINVAL;
+       }
+
+       if (op == DFU_OP_WRITE)
+               memcpy(dfu->data.ram.start + offset, buf, *len);
+       else
+               memcpy(buf, dfu->data.ram.start + offset, *len);
+
+       return 0;
+}
+
+static int dfu_write_medium_ram(struct dfu_entity *dfu, u64 offset,
+                               void *buf, long *len)
+{
+       return dfu_transfer_medium_ram(DFU_OP_WRITE, dfu, offset, buf, len);
+}
+
+static int dfu_read_medium_ram(struct dfu_entity *dfu, u64 offset,
+                              void *buf, long *len)
+{
+       if (!*len) {
+               *len = dfu->data.ram.size;
+               return 0;
+       }
+
+       return dfu_transfer_medium_ram(DFU_OP_READ, dfu, offset, buf, len);
+}
+
+int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
+{
+       char *st;
+
+       dfu->dev_type = DFU_DEV_RAM;
+       st = strsep(&s, " ");
+       if (strcmp(st, "ram")) {
+               error("unsupported device: %s\n", st);
+               return -ENODEV;
+       }
+
+       dfu->layout = DFU_RAM_ADDR;
+       dfu->data.ram.start = (void *)simple_strtoul(s, &s, 16);
+       s++;
+       dfu->data.ram.size = simple_strtoul(s, &s, 16);
+
+       dfu->write_medium = dfu_write_medium_ram;
+       dfu->read_medium = dfu_read_medium_ram;
+
+       dfu->inited = 0;
+
+       return 0;
+}
index bedf833f70dfac17344af3195cfb33582c96ab34..06280d1fa6bb65d62b7873f04505992f85f371ec 100644 (file)
@@ -34,6 +34,8 @@ COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o
 COBJS-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
 ifdef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
+else
+COBJS-$(CONFIG_GENERIC_MMC) += mmc_write.o
 endif
 
 COBJS  := $(COBJS-y)
index a82ee17a2503b51f8991f4171a1e9f45840dd80b..9a803a02d4f989b968e30cb076784bf04b6bba6e 100644 (file)
@@ -41,12 +41,11 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac,
 }
 
 static void dwmci_prepare_data(struct dwmci_host *host,
-               struct mmc_data *data)
+               struct mmc_data *data, struct dwmci_idmac *cur_idmac)
 {
        unsigned long ctrl;
        unsigned int i = 0, flags, cnt, blk_cnt;
        ulong data_start, data_end, start_addr;
-       ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data->blocks);
 
 
        blk_cnt = data->blocks;
@@ -73,7 +72,7 @@ static void dwmci_prepare_data(struct dwmci_host *host,
                dwmci_set_idma_desc(cur_idmac, flags, cnt,
                                start_addr + (i * PAGE_SIZE));
 
-               if(blk_cnt < 8)
+               if (blk_cnt <= 8)
                        break;
                blk_cnt -= 8;
                cur_idmac++;
@@ -111,6 +110,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                struct mmc_data *data)
 {
        struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+       ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
+                                data ? DIV_ROUND_UP(data->blocks, 8) : 0);
        int flags = 0, i;
        unsigned int timeout = 100000;
        u32 retry = 10000;
@@ -127,7 +128,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
 
        if (data)
-               dwmci_prepare_data(host, data);
+               dwmci_prepare_data(host, data, cur_idmac);
 
        dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
 
index 55026759ede4d41cbb26e2096a965e87e9b812b6..84dae4d8bd8055d9f5cd78a6b421d7413a61f24c 100644 (file)
@@ -15,6 +15,7 @@
 #include <malloc.h>
 #include <linux/list.h>
 #include <div64.h>
+#include "mmc_private.h"
 
 /* Set block count limit because of 16 bit register limit on some hardware*/
 #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
@@ -52,14 +53,10 @@ int __board_mmc_getcd(struct mmc *mmc) {
 int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
        alias("__board_mmc_getcd")));
 
-static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
-                       struct mmc_data *data)
+int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
-       struct mmc_data backup;
        int ret;
 
-       memset(&backup, 0, sizeof(backup));
-
 #ifdef CONFIG_MMC_TRACE
        int i;
        u8 *ptr;
@@ -114,7 +111,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        return ret;
 }
 
-static int mmc_send_status(struct mmc *mmc, int timeout)
+int mmc_send_status(struct mmc *mmc, int timeout)
 {
        struct mmc_cmd cmd;
        int err, retries = 5;
@@ -135,8 +132,10 @@ static int mmc_send_status(struct mmc *mmc, int timeout)
                             MMC_STATE_PRG)
                                break;
                        else if (cmd.response[0] & MMC_STATUS_MASK) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                                printf("Status Error: 0x%08X\n",
                                        cmd.response[0]);
+#endif
                                return COMM_ERR;
                        }
                } else if (--retries < 0)
@@ -151,14 +150,16 @@ static int mmc_send_status(struct mmc *mmc, int timeout)
        printf("CURR STATE:%d\n", status);
 #endif
        if (timeout <= 0) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("Timeout waiting card ready\n");
+#endif
                return TIMEOUT;
        }
 
        return 0;
 }
 
-static int mmc_set_blocklen(struct mmc *mmc, int len)
+int mmc_set_blocklen(struct mmc *mmc, int len)
 {
        struct mmc_cmd cmd;
 
@@ -181,179 +182,13 @@ struct mmc *find_mmc_device(int dev_num)
                        return m;
        }
 
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
        printf("MMC Device %d not found\n", dev_num);
+#endif
 
        return NULL;
 }
 
-static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
-{
-       struct mmc_cmd cmd;
-       ulong end;
-       int err, start_cmd, end_cmd;
-
-       if (mmc->high_capacity)
-               end = start + blkcnt - 1;
-       else {
-               end = (start + blkcnt - 1) * mmc->write_bl_len;
-               start *= mmc->write_bl_len;
-       }
-
-       if (IS_SD(mmc)) {
-               start_cmd = SD_CMD_ERASE_WR_BLK_START;
-               end_cmd = SD_CMD_ERASE_WR_BLK_END;
-       } else {
-               start_cmd = MMC_CMD_ERASE_GROUP_START;
-               end_cmd = MMC_CMD_ERASE_GROUP_END;
-       }
-
-       cmd.cmdidx = start_cmd;
-       cmd.cmdarg = start;
-       cmd.resp_type = MMC_RSP_R1;
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err)
-               goto err_out;
-
-       cmd.cmdidx = end_cmd;
-       cmd.cmdarg = end;
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err)
-               goto err_out;
-
-       cmd.cmdidx = MMC_CMD_ERASE;
-       cmd.cmdarg = SECURE_ERASE;
-       cmd.resp_type = MMC_RSP_R1b;
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err)
-               goto err_out;
-
-       return 0;
-
-err_out:
-       puts("mmc erase failed\n");
-       return err;
-}
-
-static unsigned long
-mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
-{
-       int err = 0;
-       struct mmc *mmc = find_mmc_device(dev_num);
-       lbaint_t blk = 0, blk_r = 0;
-       int timeout = 1000;
-
-       if (!mmc)
-               return -1;
-
-       if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
-               printf("\n\nCaution! Your devices Erase group is 0x%x\n"
-                      "The erase range would be change to "
-                      "0x" LBAF "~0x" LBAF "\n\n",
-                      mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
-                      ((start + blkcnt + mmc->erase_grp_size)
-                      & ~(mmc->erase_grp_size - 1)) - 1);
-
-       while (blk < blkcnt) {
-               blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
-                       mmc->erase_grp_size : (blkcnt - blk);
-               err = mmc_erase_t(mmc, start + blk, blk_r);
-               if (err)
-                       break;
-
-               blk += blk_r;
-
-               /* Waiting for the ready status */
-               if (mmc_send_status(mmc, timeout))
-                       return 0;
-       }
-
-       return blk;
-}
-
-static ulong
-mmc_write_blocks(struct mmc *mmc, lbaint_t start, lbaint_t blkcnt, const void*src)
-{
-       struct mmc_cmd cmd;
-       struct mmc_data data;
-       int timeout = 1000;
-
-       if ((start + blkcnt) > mmc->block_dev.lba) {
-               printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
-                       start + blkcnt, mmc->block_dev.lba);
-               return 0;
-       }
-
-       if (blkcnt == 0)
-               return 0;
-       else if (blkcnt == 1)
-               cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
-       else
-               cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
-
-       if (mmc->high_capacity)
-               cmd.cmdarg = start;
-       else
-               cmd.cmdarg = start * mmc->write_bl_len;
-
-       cmd.resp_type = MMC_RSP_R1;
-
-       data.src = src;
-       data.blocks = blkcnt;
-       data.blocksize = mmc->write_bl_len;
-       data.flags = MMC_DATA_WRITE;
-
-       if (mmc_send_cmd(mmc, &cmd, &data)) {
-               printf("mmc write failed\n");
-               return 0;
-       }
-
-       /* SPI multiblock writes terminate using a special
-        * token, not a STOP_TRANSMISSION request.
-        */
-       if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
-               cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
-               cmd.cmdarg = 0;
-               cmd.resp_type = MMC_RSP_R1b;
-               if (mmc_send_cmd(mmc, &cmd, NULL)) {
-                       printf("mmc fail to send stop cmd\n");
-                       return 0;
-               }
-       }
-
-       /* Waiting for the ready status */
-       if (mmc_send_status(mmc, timeout))
-               return 0;
-
-       return blkcnt;
-}
-
-static ulong
-mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void*src)
-{
-       lbaint_t cur, blocks_todo = blkcnt;
-
-       struct mmc *mmc = find_mmc_device(dev_num);
-       if (!mmc)
-               return 0;
-
-       if (mmc_set_blocklen(mmc, mmc->write_bl_len))
-               return 0;
-
-       do {
-               cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
-               if(mmc_write_blocks(mmc, start, cur, src) != cur)
-                       return 0;
-               blocks_todo -= cur;
-               start += cur;
-               src += cur * mmc->write_bl_len;
-       } while (blocks_todo > 0);
-
-       return blkcnt;
-}
-
 static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
                           lbaint_t blkcnt)
 {
@@ -385,7 +220,9 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
                cmd.cmdarg = 0;
                cmd.resp_type = MMC_RSP_R1b;
                if (mmc_send_cmd(mmc, &cmd, NULL)) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                        printf("mmc fail to send stop cmd\n");
+#endif
                        return 0;
                }
        }
@@ -405,8 +242,10 @@ static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
                return 0;
 
        if ((start + blkcnt) > mmc->block_dev.lba) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
                        start + blkcnt, mmc->block_dev.lba);
+#endif
                return 0;
        }
 
@@ -1268,6 +1107,7 @@ static int mmc_startup(struct mmc *mmc)
        mmc->block_dev.blksz = mmc->read_bl_len;
        mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
        mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
        sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
                mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
                (mmc->cid[3] >> 16) & 0xffff);
@@ -1277,6 +1117,11 @@ static int mmc_startup(struct mmc *mmc)
                (mmc->cid[2] >> 24) & 0xff);
        sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
                (mmc->cid[2] >> 16) & 0xf);
+#else
+       mmc->block_dev.vendor[0] = 0;
+       mmc->block_dev.product[0] = 0;
+       mmc->block_dev.revision[0] = 0;
+#endif
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
        init_part(&mmc->block_dev);
 #endif
@@ -1343,7 +1188,9 @@ int mmc_start_init(struct mmc *mmc)
 
        if (mmc_getcd(mmc) == 0) {
                mmc->has_init = 0;
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: no card present\n");
+#endif
                return NO_CARD_ERR;
        }
 
@@ -1378,7 +1225,9 @@ int mmc_start_init(struct mmc *mmc)
                err = mmc_send_op_cond(mmc);
 
                if (err && err != IN_PROGRESS) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                        printf("Card did not respond to voltage select!\n");
+#endif
                        return UNUSABLE_ERR;
                }
        }
@@ -1434,6 +1283,8 @@ static int __def_mmc_init(bd_t *bis)
 int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+
 void print_mmc_devices(char separator)
 {
        struct mmc *m;
@@ -1451,6 +1302,10 @@ void print_mmc_devices(char separator)
        printf("\n");
 }
 
+#else
+void print_mmc_devices(char separator) { }
+#endif
+
 int get_mmc_num(void)
 {
        return cur_dev_num;
diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h
new file mode 100644 (file)
index 0000000..16dcf9f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008,2010 Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based (loosely) on the Linux code
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _MMC_PRIVATE_H_
+#define _MMC_PRIVATE_H_
+
+#include <mmc.h>
+
+extern int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+                       struct mmc_data *data);
+extern int mmc_send_status(struct mmc *mmc, int timeout);
+extern int mmc_set_blocklen(struct mmc *mmc, int len);
+
+#ifndef CONFIG_SPL_BUILD
+
+extern unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt);
+
+extern ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt,
+               const void *src);
+
+#else /* CONFIG_SPL_BUILD */
+
+/* SPL will never write or erase, declare dummies to reduce code size. */
+
+static inline unsigned long mmc_berase(int dev_num, lbaint_t start,
+               lbaint_t blkcnt)
+{
+       return 0;
+}
+
+static inline ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt,
+               const void *src)
+{
+       return 0;
+}
+
+#endif /* CONFIG_SPL_BUILD */
+
+#endif /* _MMC_PRIVATE_H_ */
diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
new file mode 100644 (file)
index 0000000..aa2fdef
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the Linux code
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <part.h>
+#include "mmc_private.h"
+
+static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
+{
+       struct mmc_cmd cmd;
+       ulong end;
+       int err, start_cmd, end_cmd;
+
+       if (mmc->high_capacity) {
+               end = start + blkcnt - 1;
+       } else {
+               end = (start + blkcnt - 1) * mmc->write_bl_len;
+               start *= mmc->write_bl_len;
+       }
+
+       if (IS_SD(mmc)) {
+               start_cmd = SD_CMD_ERASE_WR_BLK_START;
+               end_cmd = SD_CMD_ERASE_WR_BLK_END;
+       } else {
+               start_cmd = MMC_CMD_ERASE_GROUP_START;
+               end_cmd = MMC_CMD_ERASE_GROUP_END;
+       }
+
+       cmd.cmdidx = start_cmd;
+       cmd.cmdarg = start;
+       cmd.resp_type = MMC_RSP_R1;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err)
+               goto err_out;
+
+       cmd.cmdidx = end_cmd;
+       cmd.cmdarg = end;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err)
+               goto err_out;
+
+       cmd.cmdidx = MMC_CMD_ERASE;
+       cmd.cmdarg = SECURE_ERASE;
+       cmd.resp_type = MMC_RSP_R1b;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err)
+               goto err_out;
+
+       return 0;
+
+err_out:
+       puts("mmc erase failed\n");
+       return err;
+}
+
+unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
+{
+       int err = 0;
+       struct mmc *mmc = find_mmc_device(dev_num);
+       lbaint_t blk = 0, blk_r = 0;
+       int timeout = 1000;
+
+       if (!mmc)
+               return -1;
+
+       if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
+               printf("\n\nCaution! Your devices Erase group is 0x%x\n"
+                      "The erase range would be change to "
+                      "0x" LBAF "~0x" LBAF "\n\n",
+                      mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
+                      ((start + blkcnt + mmc->erase_grp_size)
+                      & ~(mmc->erase_grp_size - 1)) - 1);
+
+       while (blk < blkcnt) {
+               blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
+                       mmc->erase_grp_size : (blkcnt - blk);
+               err = mmc_erase_t(mmc, start + blk, blk_r);
+               if (err)
+                       break;
+
+               blk += blk_r;
+
+               /* Waiting for the ready status */
+               if (mmc_send_status(mmc, timeout))
+                       return 0;
+       }
+
+       return blk;
+}
+
+static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
+               lbaint_t blkcnt, const void *src)
+{
+       struct mmc_cmd cmd;
+       struct mmc_data data;
+       int timeout = 1000;
+
+       if ((start + blkcnt) > mmc->block_dev.lba) {
+               printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
+                      start + blkcnt, mmc->block_dev.lba);
+               return 0;
+       }
+
+       if (blkcnt == 0)
+               return 0;
+       else if (blkcnt == 1)
+               cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
+       else
+               cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
+
+       if (mmc->high_capacity)
+               cmd.cmdarg = start;
+       else
+               cmd.cmdarg = start * mmc->write_bl_len;
+
+       cmd.resp_type = MMC_RSP_R1;
+
+       data.src = src;
+       data.blocks = blkcnt;
+       data.blocksize = mmc->write_bl_len;
+       data.flags = MMC_DATA_WRITE;
+
+       if (mmc_send_cmd(mmc, &cmd, &data)) {
+               printf("mmc write failed\n");
+               return 0;
+       }
+
+       /* SPI multiblock writes terminate using a special
+        * token, not a STOP_TRANSMISSION request.
+        */
+       if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
+               cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+               cmd.cmdarg = 0;
+               cmd.resp_type = MMC_RSP_R1b;
+               if (mmc_send_cmd(mmc, &cmd, NULL)) {
+                       printf("mmc fail to send stop cmd\n");
+                       return 0;
+               }
+       }
+
+       /* Waiting for the ready status */
+       if (mmc_send_status(mmc, timeout))
+               return 0;
+
+       return blkcnt;
+}
+
+ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void *src)
+{
+       lbaint_t cur, blocks_todo = blkcnt;
+
+       struct mmc *mmc = find_mmc_device(dev_num);
+       if (!mmc)
+               return 0;
+
+       if (mmc_set_blocklen(mmc, mmc->write_bl_len))
+               return 0;
+
+       do {
+               cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
+               if (mmc_write_blocks(mmc, start, cur, src) != cur)
+                       return 0;
+               blocks_todo -= cur;
+               start += cur;
+               src += cur * mmc->write_bl_len;
+       } while (blocks_todo > 0);
+
+       return blkcnt;
+}
index 975b2c5ba4d74b1ae875a205341efec5bd233e82..d3a8b5303d534efbfc68fd412635e5e082798a27 100644 (file)
@@ -288,6 +288,30 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
 
        mmc_reg_out(&mmc_base->sysctl, bit, bit);
 
+       /*
+        * CMD(DAT) lines reset procedures are slightly different
+        * for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).
+        * According to OMAP3 TRM:
+        * Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until it
+        * returns to 0x0.
+        * According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
+        * procedure steps must be as follows:
+        * 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
+        *    MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
+        * 2. Poll the SRC(SRD) bit until it is set to 0x1.
+        * 3. Wait until the SRC (SRD) bit returns to 0x0
+        *    (reset procedure is completed).
+        */
+#if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
+       defined(CONFIG_AM33XX)
+       if (!(readl(&mmc_base->sysctl) & bit)) {
+               start = get_timer(0);
+               while (!(readl(&mmc_base->sysctl) & bit)) {
+                       if (get_timer(0) - start > MAX_RETRY_MS)
+                               return;
+               }
+       }
+#endif
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & bit) != 0) {
                if (get_timer(0) - start > MAX_RETRY_MS) {
@@ -376,6 +400,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        }
 
        writel(cmd->cmdarg, &mmc_base->arg);
+       udelay(20);             /* To fix "No status update" error on eMMC */
        writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
 
        start = get_timer(0);
@@ -480,7 +505,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
        unsigned int count;
 
        /*
-        * Start Polled Read
+        * Start Polled Write
         */
        count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size;
        count /= 4;
@@ -586,6 +611,8 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
 {
        struct mmc *mmc = &hsmmc_dev[dev_index];
        struct omap_hsmmc_data *priv_data = &hsmmc_dev_data[dev_index];
+       uint host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
+                            MMC_MODE_HC;
 
        sprintf(mmc->name, "OMAP SD/MMC");
        mmc->send_cmd = mmc_send_cmd;
@@ -600,11 +627,20 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
 #ifdef OMAP_HSMMC2_BASE
        case 1:
                priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
+#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
+     defined(CONFIG_DRA7XX)) && defined(CONFIG_HSMMC2_8BIT)
+               /* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
+               host_caps_val |= MMC_MODE_8BIT;
+#endif
                break;
 #endif
 #ifdef OMAP_HSMMC3_BASE
        case 2:
                priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
+#if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT)
+               /* Enable 8-bit interface for eMMC on DRA7XX */
+               host_caps_val |= MMC_MODE_8BIT;
+#endif
                break;
 #endif
        default:
@@ -620,8 +656,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                mmc->getwp = omap_mmc_getwp;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-       mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
-                               MMC_MODE_HC) & ~host_caps_mask;
+       mmc->host_caps = host_caps_val & ~host_caps_mask;
 
        mmc->f_min = 400000;
 
index 7f89403b432f87155d95d8ef4618a8a5b18e1968..40ff8739bfeae6ba48bb2f9497d61f8d8061afb3 100644 (file)
@@ -72,7 +72,7 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width)
 
        host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE |
                SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR |
-               SDHCI_QUIRK_WAIT_SEND_CMD;
+               SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_USE_WIDE8;
        host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
        host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 
@@ -81,6 +81,8 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width)
        host->index = index;
 
        host->host_caps = MMC_MODE_HC;
+       if (bus_width == 8)
+               host->host_caps |= MMC_MODE_8BIT;
 
        return add_sdhci(host, 52000000, 400000);
 }
index 42619916e5c3a80afa6b4579877a48667a88fd2c..dfb2eeeb4de8321004afeddf8358ea9909ed62b1 100644 (file)
@@ -68,10 +68,9 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
        unsigned int stat, rdy, mask, timeout, block = 0;
 #ifdef CONFIG_MMC_SDMA
        unsigned char ctrl;
-       ctrl = sdhci_readl(host, SDHCI_HOST_CONTROL);
+       ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
        ctrl &= ~SDHCI_CTRL_DMA_MASK;
-       ctrl |= SDHCI_CTRL_SDMA;
-       sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL);
+       sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 #endif
 
        timeout = 1000000;
@@ -254,7 +253,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
        if (clock == 0)
                return 0;
 
-       if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) {
+       if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
                /* Version 3.00 divisors must be a multiple of 2. */
                if (mmc->f_max <= clock)
                        div = 1;
@@ -347,10 +346,11 @@ void sdhci_set_ios(struct mmc *mmc)
        ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
        if (mmc->bus_width == 8) {
                ctrl &= ~SDHCI_CTRL_4BITBUS;
-               if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+               if ((SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) ||
+                               (host->quirks & SDHCI_QUIRK_USE_WIDE8))
                        ctrl |= SDHCI_CTRL_8BITBUS;
        } else {
-               if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+               if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
                        ctrl &= ~SDHCI_CTRL_8BITBUS;
                if (mmc->bus_width == 4)
                        ctrl |= SDHCI_CTRL_4BITBUS;
@@ -437,7 +437,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
        if (max_clk)
                mmc->f_max = max_clk;
        else {
-               if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+               if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
                        mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
                                >> SDHCI_CLOCK_BASE_SHIFT;
                else
@@ -452,7 +452,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
        if (min_clk)
                mmc->f_min = min_clk;
        else {
-               if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300)
+               if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
                        mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300;
                else
                        mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200;
@@ -470,7 +470,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
                mmc->voltages |= host->voltages;
 
        mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
-       if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) {
+       if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
                if (caps & SDHCI_CAN_DO_8BIT)
                        mmc->host_caps |= MMC_MODE_8BIT;
        }
index 49c08145a7fa63296cdb79dc058af7108b64a72b..deda5f2449d1fb8feaf6132c7f52abb2b4aaaab7 100644 (file)
@@ -217,11 +217,23 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
             u_char *buf)
 {
+       int ret_code;
        if (from < 0 || from > mtd->size || len > mtd->size - from)
                return -EINVAL;
        if (!len)
                return 0;
-       return mtd->_read(mtd, from, len, retlen, buf);
+
+       /*
+        * In the absence of an error, drivers return a non-negative integer
+        * representing the maximum number of bitflips that were corrected on
+        * any one ecc region (if applicable; zero otherwise).
+        */
+       ret_code = mtd->_read(mtd, from, len, retlen, buf);
+       if (unlikely(ret_code < 0))
+               return ret_code;
+       if (mtd->ecc_strength == 0)
+               return 0;       /* device lacks ecc */
+       return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
 }
 
 int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
index 9dfe7bbc9a9244dbb7e56f328b3046d2d2c3fbe0..146ce11eb1bafcfbb8f0add516c5675d0f166bc7 100644 (file)
@@ -53,12 +53,12 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
 
        stats = part->master->ecc_stats;
        res = mtd_read(part->master, from + part->offset, len, retlen, buf);
-       if (unlikely(res)) {
-               if (mtd_is_bitflip(res))
-                       mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
-               if (mtd_is_eccerr(res))
-                       mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
-       }
+       if (unlikely(mtd_is_eccerr(res)))
+               mtd->ecc_stats.failed +=
+                       part->master->ecc_stats.failed - stats.failed;
+       else
+               mtd->ecc_stats.corrected +=
+                       part->master->ecc_stats.corrected - stats.corrected;
        return res;
 }
 
index 9e05cef4179f3ddfc10e26f7e116f32c399364e2..d4d586c94265f2e4834dd05995911b260007aea4 100644 (file)
@@ -1238,6 +1238,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                mtd->oobavail : mtd->oobsize;
 
        uint8_t *bufpoi, *oob, *buf;
+       unsigned int max_bitflips = 0;
 
        stats = mtd->ecc_stats;
 
@@ -1265,7 +1266,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
                        chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
 
-                       /* Now read the page into the buffer */
+                       /*
+                        * Now read the page into the buffer.  Absent an error,
+                        * the read methods return max bitflips per ecc step.
+                        */
                        if (unlikely(ops->mode == MTD_OPS_RAW))
                                ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
                                                              oob_required,
@@ -1284,15 +1288,19 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                                break;
                        }
 
+                       max_bitflips = max_t(unsigned int, max_bitflips, ret);
+
                        /* Transfer not aligned data */
                        if (!aligned) {
                                if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
                                    !(mtd->ecc_stats.failed - stats.failed) &&
-                                   (ops->mode != MTD_OPS_RAW))
+                                   (ops->mode != MTD_OPS_RAW)) {
                                        chip->pagebuf = realpage;
-                               else
+                                       chip->pagebuf_bitflips = ret;
+                               } else {
                                        /* Invalidate page cache */
                                        chip->pagebuf = -1;
+                               }
                                memcpy(buf, chip->buffers->databuf + col, bytes);
                        }
 
@@ -1310,6 +1318,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                } else {
                        memcpy(buf, chip->buffers->databuf + col, bytes);
                        buf += bytes;
+                       max_bitflips = max_t(unsigned int, max_bitflips,
+                                            chip->pagebuf_bitflips);
                }
 
                readlen -= bytes;
@@ -1341,7 +1351,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
        if (mtd->ecc_stats.failed - stats.failed)
                return -EBADMSG;
 
-       return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+       return max_bitflips;
 }
 
 /**
index ddfe7e7c756dbff2cb385d88e5bbc27b0a496369..067f8ef184b59356f00f1e955a21ce863accd642 100644 (file)
@@ -969,7 +969,8 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
        if (mtd->ecc_stats.failed - stats.failed)
                return -EBADMSG;
 
-       return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+       /* return max bitflips per ecc step; ONENANDs correct 1 bit only */
+       return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
 }
 
 /**
index 191138ad188edaca986b3c8feda9233b8b6c7c3f..86ffc59d039ecb040eab8c2a2a770c4571cb30f7 100644 (file)
@@ -14,16 +14,11 @@ COBJS-$(CONFIG_SPL_SPI_LOAD)        += spi_spl_load.o
 COBJS-$(CONFIG_SPL_SPI_BOOT)   += fsl_espi_spl.o
 endif
 
-COBJS-$(CONFIG_SPI_FLASH)      += spi_flash.o
-COBJS-$(CONFIG_SPI_FLASH_ATMEL)        += atmel.o
-COBJS-$(CONFIG_SPI_FLASH_EON)  += eon.o
-COBJS-$(CONFIG_SPI_FLASH_GIGADEVICE)   += gigadevice.o
-COBJS-$(CONFIG_SPI_FLASH_MACRONIX)     += macronix.o
-COBJS-$(CONFIG_SPI_FLASH_SPANSION)     += spansion.o
-COBJS-$(CONFIG_SPI_FLASH_SST)  += sst.o
-COBJS-$(CONFIG_SPI_FLASH_STMICRO)      += stmicro.o
-COBJS-$(CONFIG_SPI_FLASH_WINBOND)      += winbond.o
-COBJS-$(CONFIG_SPI_FRAM_RAMTRON)       += ramtron.o
+ifdef CONFIG_CMD_SF
+COBJS-y        += sf.o
+endif
+COBJS-$(CONFIG_SPI_FLASH) += sf_probe.o sf_ops.o
+COBJS-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.o
 COBJS-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
 
 COBJS  := $(COBJS-y)
diff --git a/drivers/mtd/spi/atmel.c b/drivers/mtd/spi/atmel.c
deleted file mode 100644 (file)
index f34df43..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Atmel SPI DataFlash support
- *
- * Copyright (C) 2008 Atmel Corporation
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-/* AT45-specific commands */
-#define CMD_AT45_READ_STATUS           0xd7
-#define CMD_AT45_ERASE_PAGE            0x81
-#define CMD_AT45_LOAD_PROG_BUF1                0x82
-#define CMD_AT45_LOAD_BUF1             0x84
-#define CMD_AT45_LOAD_PROG_BUF2                0x85
-#define CMD_AT45_LOAD_BUF2             0x87
-#define CMD_AT45_PROG_BUF1             0x88
-#define CMD_AT45_PROG_BUF2             0x89
-
-/* AT45 status register bits */
-#define AT45_STATUS_P2_PAGE_SIZE       (1 << 0)
-#define AT45_STATUS_READY              (1 << 7)
-
-/* DataFlash family IDs, as obtained from the second idcode byte */
-#define DF_FAMILY_AT26F                        0
-#define DF_FAMILY_AT45                 1
-#define DF_FAMILY_AT26DF               2       /* AT25DF and AT26DF */
-
-struct atmel_spi_flash_params {
-       u8              idcode1;
-       /* Log2 of page size in power-of-two mode */
-       u8              l2_page_size;
-       u8              pages_per_block;
-       u8              blocks_per_sector;
-       u8              nr_sectors;
-       const char      *name;
-};
-
-/* spi_flash needs to be first so upper layers can free() it */
-struct atmel_spi_flash {
-       struct spi_flash flash;
-       const struct atmel_spi_flash_params *params;
-};
-
-static inline struct atmel_spi_flash *
-to_atmel_spi_flash(struct spi_flash *flash)
-{
-       return container_of(flash, struct atmel_spi_flash, flash);
-}
-
-static const struct atmel_spi_flash_params atmel_spi_flash_table[] = {
-       {
-               .idcode1                = 0x22,
-               .l2_page_size           = 8,
-               .pages_per_block        = 8,
-               .blocks_per_sector      = 16,
-               .nr_sectors             = 4,
-               .name                   = "AT45DB011D",
-       },
-       {
-               .idcode1                = 0x23,
-               .l2_page_size           = 8,
-               .pages_per_block        = 8,
-               .blocks_per_sector      = 16,
-               .nr_sectors             = 8,
-               .name                   = "AT45DB021D",
-       },
-       {
-               .idcode1                = 0x24,
-               .l2_page_size           = 8,
-               .pages_per_block        = 8,
-               .blocks_per_sector      = 32,
-               .nr_sectors             = 8,
-               .name                   = "AT45DB041D",
-       },
-       {
-               .idcode1                = 0x25,
-               .l2_page_size           = 8,
-               .pages_per_block        = 8,
-               .blocks_per_sector      = 32,
-               .nr_sectors             = 16,
-               .name                   = "AT45DB081D",
-       },
-       {
-               .idcode1                = 0x26,
-               .l2_page_size           = 9,
-               .pages_per_block        = 8,
-               .blocks_per_sector      = 32,
-               .nr_sectors             = 16,
-               .name                   = "AT45DB161D",
-       },
-       {
-               .idcode1                = 0x27,
-               .l2_page_size           = 9,
-               .pages_per_block        = 8,
-               .blocks_per_sector      = 64,
-               .nr_sectors             = 64,
-               .name                   = "AT45DB321D",
-       },
-       {
-               .idcode1                = 0x28,
-               .l2_page_size           = 10,
-               .pages_per_block        = 8,
-               .blocks_per_sector      = 32,
-               .nr_sectors             = 32,
-               .name                   = "AT45DB642D",
-       },
-       {
-               .idcode1                = 0x47,
-               .l2_page_size           = 8,
-               .pages_per_block        = 16,
-               .blocks_per_sector      = 16,
-               .nr_sectors             = 64,
-               .name                   = "AT25DF321",
-       },
-};
-
-static int at45_wait_ready(struct spi_flash *flash, unsigned long timeout)
-{
-       struct spi_slave *spi = flash->spi;
-       unsigned long timebase;
-       int ret;
-       u8 cmd = CMD_AT45_READ_STATUS;
-       u8 status;
-
-       timebase = get_timer(0);
-
-       ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
-       if (ret)
-               return -1;
-
-       do {
-               ret = spi_xfer(spi, 8, NULL, &status, 0);
-               if (ret)
-                       return -1;
-
-               if (status & AT45_STATUS_READY)
-                       break;
-       } while (get_timer(timebase) < timeout);
-
-       /* Deactivate CS */
-       spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
-
-       if (status & AT45_STATUS_READY)
-               return 0;
-
-       /* Timed out */
-       return -1;
-}
-
-/*
- * Assemble the address part of a command for AT45 devices in
- * non-power-of-two page size mode.
- */
-static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset)
-{
-       unsigned long page_addr;
-       unsigned long byte_addr;
-       unsigned long page_size;
-       unsigned int page_shift;
-
-       /*
-        * The "extra" space per page is the power-of-two page size
-        * divided by 32.
-        */
-       page_shift = asf->params->l2_page_size;
-       page_size = (1 << page_shift) + (1 << (page_shift - 5));
-       page_shift++;
-       page_addr = offset / page_size;
-       byte_addr = offset % page_size;
-
-       cmd[0] = page_addr >> (16 - page_shift);
-       cmd[1] = page_addr << (page_shift - 8) | (byte_addr >> 8);
-       cmd[2] = byte_addr;
-}
-
-static int dataflash_read_fast_at45(struct spi_flash *flash,
-               u32 offset, size_t len, void *buf)
-{
-       struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
-       u8 cmd[5];
-
-       cmd[0] = CMD_READ_ARRAY_FAST;
-       at45_build_address(asf, cmd + 1, offset);
-       cmd[4] = 0x00;
-
-       return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
-}
-
-/*
- * TODO: the two write funcs (_p2/_at45) should get unified ...
- */
-static int dataflash_write_p2(struct spi_flash *flash,
-               u32 offset, size_t len, const void *buf)
-{
-       struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
-       unsigned long page_size;
-       u32 addr = offset;
-       size_t chunk_len;
-       size_t actual;
-       int ret;
-       u8 cmd[4];
-
-       /*
-        * TODO: This function currently uses only page buffer #1.  We can
-        * speed this up by using both buffers and loading one buffer while
-        * the other is being programmed into main memory.
-        */
-
-       page_size = (1 << asf->params->l2_page_size);
-
-       ret = spi_claim_bus(flash->spi);
-       if (ret) {
-               debug("SF: Unable to claim SPI bus\n");
-               return ret;
-       }
-
-       for (actual = 0; actual < len; actual += chunk_len) {
-               chunk_len = min(len - actual, page_size - (addr % page_size));
-
-               /* Use the same address bits for both commands */
-               cmd[0] = CMD_AT45_LOAD_BUF1;
-               cmd[1] = addr >> 16;
-               cmd[2] = addr >> 8;
-               cmd[3] = addr;
-
-               ret = spi_flash_cmd_write(flash->spi, cmd, 4,
-                               buf + actual, chunk_len);
-               if (ret < 0) {
-                       debug("SF: Loading AT45 buffer failed\n");
-                       goto out;
-               }
-
-               cmd[0] = CMD_AT45_PROG_BUF1;
-               ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-               if (ret < 0) {
-                       debug("SF: AT45 page programming failed\n");
-                       goto out;
-               }
-
-               ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
-               if (ret < 0) {
-                       debug("SF: AT45 page programming timed out\n");
-                       goto out;
-               }
-
-               addr += chunk_len;
-       }
-
-       debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
-             len, offset);
-       ret = 0;
-
-out:
-       spi_release_bus(flash->spi);
-       return ret;
-}
-
-static int dataflash_write_at45(struct spi_flash *flash,
-               u32 offset, size_t len, const void *buf)
-{
-       struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
-       unsigned long page_addr;
-       unsigned long byte_addr;
-       unsigned long page_size;
-       unsigned int page_shift;
-       size_t chunk_len;
-       size_t actual;
-       int ret;
-       u8 cmd[4];
-
-       /*
-        * TODO: This function currently uses only page buffer #1.  We can
-        * speed this up by using both buffers and loading one buffer while
-        * the other is being programmed into main memory.
-        */
-
-       page_shift = asf->params->l2_page_size;
-       page_size = (1 << page_shift) + (1 << (page_shift - 5));
-       page_shift++;
-       page_addr = offset / page_size;
-       byte_addr = offset % page_size;
-
-       ret = spi_claim_bus(flash->spi);
-       if (ret) {
-               debug("SF: Unable to claim SPI bus\n");
-               return ret;
-       }
-
-       for (actual = 0; actual < len; actual += chunk_len) {
-               chunk_len = min(len - actual, page_size - byte_addr);
-
-               /* Use the same address bits for both commands */
-               cmd[0] = CMD_AT45_LOAD_BUF1;
-               cmd[1] = page_addr >> (16 - page_shift);
-               cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
-               cmd[3] = byte_addr;
-
-               ret = spi_flash_cmd_write(flash->spi, cmd, 4,
-                               buf + actual, chunk_len);
-               if (ret < 0) {
-                       debug("SF: Loading AT45 buffer failed\n");
-                       goto out;
-               }
-
-               cmd[0] = CMD_AT45_PROG_BUF1;
-               ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-               if (ret < 0) {
-                       debug("SF: AT45 page programming failed\n");
-                       goto out;
-               }
-
-               ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
-               if (ret < 0) {
-                       debug("SF: AT45 page programming timed out\n");
-                       goto out;
-               }
-
-               page_addr++;
-               byte_addr = 0;
-       }
-
-       debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
-             len, offset);
-       ret = 0;
-
-out:
-       spi_release_bus(flash->spi);
-       return ret;
-}
-
-/*
- * TODO: the two erase funcs (_p2/_at45) should get unified ...
- */
-static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len)
-{
-       struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
-       unsigned long page_size;
-
-       size_t actual;
-       int ret;
-       u8 cmd[4];
-
-       /*
-        * TODO: This function currently uses page erase only. We can
-        * probably speed things up by using block and/or sector erase
-        * when possible.
-        */
-
-       page_size = (1 << asf->params->l2_page_size);
-
-       if (offset % page_size || len % page_size) {
-               debug("SF: Erase offset/length not multiple of page size\n");
-               return -1;
-       }
-
-       cmd[0] = CMD_AT45_ERASE_PAGE;
-       cmd[3] = 0x00;
-
-       ret = spi_claim_bus(flash->spi);
-       if (ret) {
-               debug("SF: Unable to claim SPI bus\n");
-               return ret;
-       }
-
-       for (actual = 0; actual < len; actual += page_size) {
-               cmd[1] = offset >> 16;
-               cmd[2] = offset >> 8;
-
-               ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-               if (ret < 0) {
-                       debug("SF: AT45 page erase failed\n");
-                       goto out;
-               }
-
-               ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-               if (ret < 0) {
-                       debug("SF: AT45 page erase timed out\n");
-                       goto out;
-               }
-
-               offset += page_size;
-       }
-
-       debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
-             len, offset);
-       ret = 0;
-
-out:
-       spi_release_bus(flash->spi);
-       return ret;
-}
-
-static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len)
-{
-       struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
-       unsigned long page_addr;
-       unsigned long page_size;
-       unsigned int page_shift;
-       size_t actual;
-       int ret;
-       u8 cmd[4];
-
-       /*
-        * TODO: This function currently uses page erase only. We can
-        * probably speed things up by using block and/or sector erase
-        * when possible.
-        */
-
-       page_shift = asf->params->l2_page_size;
-       page_size = (1 << page_shift) + (1 << (page_shift - 5));
-       page_shift++;
-       page_addr = offset / page_size;
-
-       if (offset % page_size || len % page_size) {
-               debug("SF: Erase offset/length not multiple of page size\n");
-               return -1;
-       }
-
-       cmd[0] = CMD_AT45_ERASE_PAGE;
-       cmd[3] = 0x00;
-
-       ret = spi_claim_bus(flash->spi);
-       if (ret) {
-               debug("SF: Unable to claim SPI bus\n");
-               return ret;
-       }
-
-       for (actual = 0; actual < len; actual += page_size) {
-               cmd[1] = page_addr >> (16 - page_shift);
-               cmd[2] = page_addr << (page_shift - 8);
-
-               ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-               if (ret < 0) {
-                       debug("SF: AT45 page erase failed\n");
-                       goto out;
-               }
-
-               ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-               if (ret < 0) {
-                       debug("SF: AT45 page erase timed out\n");
-                       goto out;
-               }
-
-               page_addr++;
-       }
-
-       debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
-             len, offset);
-       ret = 0;
-
-out:
-       spi_release_bus(flash->spi);
-       return ret;
-}
-
-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
-{
-       const struct atmel_spi_flash_params *params;
-       unsigned page_size;
-       unsigned int family;
-       struct atmel_spi_flash *asf;
-       unsigned int i;
-       int ret;
-       u8 status;
-
-       for (i = 0; i < ARRAY_SIZE(atmel_spi_flash_table); i++) {
-               params = &atmel_spi_flash_table[i];
-               if (params->idcode1 == idcode[1])
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(atmel_spi_flash_table)) {
-               debug("SF: Unsupported DataFlash ID %02x\n",
-                     idcode[1]);
-               return NULL;
-       }
-
-       asf = spi_flash_alloc(struct atmel_spi_flash, spi, params->name);
-       if (!asf) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-
-       asf->params = params;
-
-       /* Assuming power-of-two page size initially. */
-       page_size = 1 << params->l2_page_size;
-
-       family = idcode[1] >> 5;
-
-       switch (family) {
-       case DF_FAMILY_AT45:
-               /*
-                * AT45 chips have configurable page size. The status
-                * register indicates which configuration is active.
-                */
-               ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1);
-               if (ret)
-                       goto err;
-
-               debug("SF: AT45 status register: %02x\n", status);
-
-               if (!(status & AT45_STATUS_P2_PAGE_SIZE)) {
-                       asf->flash.read = dataflash_read_fast_at45;
-                       asf->flash.write = dataflash_write_at45;
-                       asf->flash.erase = dataflash_erase_at45;
-                       page_size += 1 << (params->l2_page_size - 5);
-               } else {
-                       asf->flash.write = dataflash_write_p2;
-                       asf->flash.erase = dataflash_erase_p2;
-               }
-
-               asf->flash.page_size = page_size;
-               asf->flash.sector_size = page_size;
-               break;
-
-       case DF_FAMILY_AT26F:
-       case DF_FAMILY_AT26DF:
-               asf->flash.page_size = page_size;
-               asf->flash.sector_size = 4096;
-               /* clear SPRL# bit for locked flash */
-               spi_flash_cmd_write_status(&asf->flash, 0);
-               break;
-
-       default:
-               debug("SF: Unsupported DataFlash family %u\n", family);
-               goto err;
-       }
-
-       asf->flash.size = page_size * params->pages_per_block
-                               * params->blocks_per_sector
-                               * params->nr_sectors;
-
-       return &asf->flash;
-
-err:
-       free(asf);
-       return NULL;
-}
diff --git a/drivers/mtd/spi/eon.c b/drivers/mtd/spi/eon.c
deleted file mode 100644 (file)
index 25cfc12..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * (C) Copyright 2010, ucRobotics Inc.
- * Author: Chong Huang <chuang@ucrobotics.com>
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-struct eon_spi_flash_params {
-       u8 idcode1;
-       u16 nr_sectors;
-       const char *name;
-};
-
-static const struct eon_spi_flash_params eon_spi_flash_table[] = {
-       {
-               .idcode1 = 0x16,
-               .nr_sectors = 1024,
-               .name = "EN25Q32B",
-       },
-       {
-               .idcode1 = 0x18,
-               .nr_sectors = 4096,
-               .name = "EN25Q128",
-       },
-};
-
-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
-{
-       const struct eon_spi_flash_params *params;
-       struct spi_flash *flash;
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) {
-               params = &eon_spi_flash_table[i];
-               if (params->idcode1 == idcode[2])
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(eon_spi_flash_table)) {
-               debug("SF: Unsupported EON ID %02x\n", idcode[1]);
-               return NULL;
-       }
-
-       flash = spi_flash_alloc_base(spi, params->name);
-       if (!flash) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-
-       flash->page_size = 256;
-       flash->sector_size = 256 * 16 * 16;
-       flash->size = 256 * 16 * params->nr_sectors;
-
-       return flash;
-}
diff --git a/drivers/mtd/spi/gigadevice.c b/drivers/mtd/spi/gigadevice.c
deleted file mode 100644 (file)
index b42581a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Gigadevice SPI flash driver
- * Copyright 2013, Samsung Electronics Co., Ltd.
- * Author: Banajit Goswami <banajit.g@samsung.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-struct gigadevice_spi_flash_params {
-       uint16_t        id;
-       uint16_t        nr_blocks;
-       const char      *name;
-};
-
-static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = {
-       {
-               .id                     = 0x6016,
-               .nr_blocks              = 64,
-               .name                   = "GD25LQ",
-       },
-       {
-               .id                     = 0x4017,
-               .nr_blocks              = 128,
-               .name                   = "GD25Q64B",
-       },
-};
-
-struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode)
-{
-       const struct gigadevice_spi_flash_params *params;
-       struct spi_flash *flash;
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(gigadevice_spi_flash_table); i++) {
-               params = &gigadevice_spi_flash_table[i];
-               if (params->id == ((idcode[1] << 8) | idcode[2]))
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(gigadevice_spi_flash_table)) {
-               debug("SF: Unsupported Gigadevice ID %02x%02x\n",
-                     idcode[1], idcode[2]);
-               return NULL;
-       }
-
-       flash = spi_flash_alloc_base(spi, params->name);
-       if (!flash) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-       /* page_size */
-       flash->page_size = 256;
-       /* sector_size = page_size * pages_per_sector */
-       flash->sector_size = flash->page_size * 16;
-       /* size = sector_size * sector_per_block * number of blocks */
-       flash->size = flash->sector_size * 16 * params->nr_blocks;
-
-       return flash;
-}
diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
deleted file mode 100644 (file)
index 70435eb..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2009(C) Marvell International Ltd. and its affiliates
- * Prafulla Wadaskar <prafulla@marvell.com>
- *
- * Based on drivers/mtd/spi/stmicro.c
- *
- * Copyright 2008, Network Appliance Inc.
- * Jason McMullan <mcmullan@netapp.com>
- *
- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
- * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-struct macronix_spi_flash_params {
-       u16 idcode;
-       u16 nr_blocks;
-       const char *name;
-};
-
-static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
-       {
-               .idcode = 0x2013,
-               .nr_blocks = 8,
-               .name = "MX25L4005",
-       },
-       {
-               .idcode = 0x2014,
-               .nr_blocks = 16,
-               .name = "MX25L8005",
-       },
-       {
-               .idcode = 0x2015,
-               .nr_blocks = 32,
-               .name = "MX25L1605D",
-       },
-       {
-               .idcode = 0x2016,
-               .nr_blocks = 64,
-               .name = "MX25L3205D",
-       },
-       {
-               .idcode = 0x2017,
-               .nr_blocks = 128,
-               .name = "MX25L6405D",
-       },
-       {
-               .idcode = 0x2018,
-               .nr_blocks = 256,
-               .name = "MX25L12805D",
-       },
-       {
-               .idcode = 0x2618,
-               .nr_blocks = 256,
-               .name = "MX25L12855E",
-       },
-};
-
-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
-{
-       const struct macronix_spi_flash_params *params;
-       struct spi_flash *flash;
-       unsigned int i;
-       u16 id = idcode[2] | idcode[1] << 8;
-
-       for (i = 0; i < ARRAY_SIZE(macronix_spi_flash_table); i++) {
-               params = &macronix_spi_flash_table[i];
-               if (params->idcode == id)
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(macronix_spi_flash_table)) {
-               debug("SF: Unsupported Macronix ID %04x\n", id);
-               return NULL;
-       }
-
-       flash = spi_flash_alloc_base(spi, params->name);
-       if (!flash) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-
-       flash->page_size = 256;
-       flash->sector_size = 256 * 16 * 16;
-       flash->size = flash->sector_size * params->nr_blocks;
-
-       /* Clear BP# bits for read-only flash */
-       spi_flash_cmd_write_status(flash, 0);
-
-       return flash;
-}
index 38f9d69169b2ea4baa60b9f9839557e16855aad6..d50da37c89af4418b5a6ad52c297007f6bb3dfc3 100644 (file)
@@ -36,7 +36,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <spi_flash.h>
-#include "spi_flash_internal.h"
+#include "sf_internal.h"
 
 /*
  * Properties of supported FRAMs
@@ -214,7 +214,8 @@ static int ramtron_erase(struct spi_flash *flash, u32 offset, size_t len)
  * nore: we are called here with idcode pointing to the first non-0x7f byte
  * already!
  */
-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
+static struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi,
+               u8 *idcode)
 {
        const struct ramtron_spi_fram_params *params;
        struct ramtron_spi_fram *sn;
@@ -270,7 +271,7 @@ struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
        return NULL;
 
 found:
-       sn = spi_flash_alloc(struct ramtron_spi_fram, spi, params->name);
+       sn = malloc(sizeof(*sn));
        if (!sn) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
@@ -285,3 +286,118 @@ found:
 
        return &sn->flash;
 }
+
+/*
+ * The following table holds all device probe functions
+ * (All flashes are removed and implemented a common probe at
+ *  spi_flash_probe.c)
+ *
+ * shift:  number of continuation bytes before the ID
+ * idcode: the expected IDCODE or 0xff for non JEDEC devices
+ * probe:  the function to call
+ *
+ * Non JEDEC devices should be ordered in the table such that
+ * the probe functions with best detection algorithms come first.
+ *
+ * Several matching entries are permitted, they will be tried
+ * in sequence until a probe function returns non NULL.
+ *
+ * IDCODE_CONT_LEN may be redefined if a device needs to declare a
+ * larger "shift" value.  IDCODE_PART_LEN generally shouldn't be
+ * changed.  This is the max number of bytes probe functions may
+ * examine when looking up part-specific identification info.
+ *
+ * Probe functions will be given the idcode buffer starting at their
+ * manu id byte (the "idcode" in the table below).  In other words,
+ * all of the continuation bytes will be skipped (the "shift" below).
+ */
+#define IDCODE_CONT_LEN 0
+#define IDCODE_PART_LEN 5
+static const struct {
+       const u8 shift;
+       const u8 idcode;
+       struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
+} flashes[] = {
+       /* Keep it sorted by define name */
+#ifdef CONFIG_SPI_FRAM_RAMTRON
+       { 6, 0xc2, spi_fram_probe_ramtron, },
+# undef IDCODE_CONT_LEN
+# define IDCODE_CONT_LEN 6
+#endif
+#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+       { 0, 0xff, spi_fram_probe_ramtron, },
+#endif
+};
+#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
+
+struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int spi_mode)
+{
+       struct spi_slave *spi;
+       struct spi_flash *flash = NULL;
+       int ret, i, shift;
+       u8 idcode[IDCODE_LEN], *idp;
+
+       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+       if (!spi) {
+               printf("SF: Failed to set up slave\n");
+               return NULL;
+       }
+
+       ret = spi_claim_bus(spi);
+       if (ret) {
+               debug("SF: Failed to claim SPI bus: %d\n", ret);
+               goto err_claim_bus;
+       }
+
+       /* Read the ID codes */
+       ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
+       if (ret)
+               goto err_read_id;
+
+#ifdef DEBUG
+       printf("SF: Got idcodes\n");
+       print_buffer(0, idcode, 1, sizeof(idcode), 0);
+#endif
+
+       /* count the number of continuation bytes */
+       for (shift = 0, idp = idcode;
+            shift < IDCODE_CONT_LEN && *idp == 0x7f;
+            ++shift, ++idp)
+               continue;
+
+       /* search the table for matches in shift and id */
+       for (i = 0; i < ARRAY_SIZE(flashes); ++i)
+               if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
+                       /* we have a match, call probe */
+                       flash = flashes[i].probe(spi, idp);
+                       if (flash)
+                               break;
+               }
+
+       if (!flash) {
+               printf("SF: Unsupported manufacturer %02x\n", *idp);
+               goto err_manufacturer_probe;
+       }
+
+       printf("SF: Detected %s with total size ", flash->name);
+       print_size(flash->size, "");
+       puts("\n");
+
+       spi_release_bus(spi);
+
+       return flash;
+
+err_manufacturer_probe:
+err_read_id:
+       spi_release_bus(spi);
+err_claim_bus:
+       spi_free_slave(spi);
+       return NULL;
+}
+
+void spi_flash_free(struct spi_flash *flash)
+{
+       spi_free_slave(flash->spi);
+       free(flash);
+}
diff --git a/drivers/mtd/spi/sf.c b/drivers/mtd/spi/sf.c
new file mode 100644 (file)
index 0000000..ddbdda0
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * SPI flash interface
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <spi.h>
+
+static int spi_flash_read_write(struct spi_slave *spi,
+                               const u8 *cmd, size_t cmd_len,
+                               const u8 *data_out, u8 *data_in,
+                               size_t data_len)
+{
+       unsigned long flags = SPI_XFER_BEGIN;
+       int ret;
+
+       if (data_len == 0)
+               flags |= SPI_XFER_END;
+
+       ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
+       if (ret) {
+               debug("SF: Failed to send command (%zu bytes): %d\n",
+                     cmd_len, ret);
+       } else if (data_len != 0) {
+               ret = spi_xfer(spi, data_len * 8, data_out, data_in,
+                                       SPI_XFER_END);
+               if (ret)
+                       debug("SF: Failed to transfer %zu bytes of data: %d\n",
+                             data_len, ret);
+       }
+
+       return ret;
+}
+
+int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
+               size_t cmd_len, void *data, size_t data_len)
+{
+       return spi_flash_read_write(spi, cmd, cmd_len, NULL, data, data_len);
+}
+
+int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len)
+{
+       return spi_flash_cmd_read(spi, &cmd, 1, response, len);
+}
+
+int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
+               const void *data, size_t data_len)
+{
+       return spi_flash_read_write(spi, cmd, cmd_len, data, NULL, data_len);
+}
similarity index 62%
rename from drivers/mtd/spi/spi_flash_internal.h
rename to drivers/mtd/spi/sf_internal.h
index af1afa96c9dfe5d757650b84d605d4200da8a0fa..12d02f9e4169027b7641c50363bbae6597c4be0e 100644 (file)
@@ -2,42 +2,43 @@
  * SPI flash internal definitions
  *
  * Copyright (C) 2008 Atmel Corporation
+ * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
+ *
+ * Licensed under the GPL-2 or later.
  */
 
-/* Common parameters -- kind of high, but they should only occur when there
- * is a problem (and well your system already is broken), so err on the side
- * of caution in case we're dealing with slower SPI buses and/or processors.
- */
-#define SPI_FLASH_PROG_TIMEOUT         (2 * CONFIG_SYS_HZ)
-#define SPI_FLASH_PAGE_ERASE_TIMEOUT   (5 * CONFIG_SYS_HZ)
-#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ)
+#ifndef _SPI_FLASH_INTERNAL_H_
+#define _SPI_FLASH_INTERNAL_H_
 
-/* Common commands */
-#define CMD_READ_ID                    0x9f
+#define SPI_FLASH_16MB_BOUN            0x1000000
 
-#define CMD_READ_ARRAY_SLOW            0x03
-#define CMD_READ_ARRAY_FAST            0x0b
+/* SECT flags */
+#define SECT_4K                                (1 << 1)
+#define SECT_32K                       (1 << 2)
+#define E_FSR                          (1 << 3)
+
+/* Erase commands */
+#define CMD_ERASE_4K                   0x20
+#define CMD_ERASE_32K                  0x52
+#define CMD_ERASE_CHIP                 0xc7
+#define CMD_ERASE_64K                  0xd8
 
+/* Write commands */
 #define CMD_WRITE_STATUS               0x01
 #define CMD_PAGE_PROGRAM               0x02
 #define CMD_WRITE_DISABLE              0x04
 #define CMD_READ_STATUS                        0x05
-#define CMD_FLAG_STATUS                        0x70
 #define CMD_WRITE_ENABLE               0x06
-#define CMD_ERASE_4K                   0x20
-#define CMD_ERASE_32K                  0x52
-#define CMD_ERASE_64K                  0xd8
-#define CMD_ERASE_CHIP                 0xc7
-
-#define SPI_FLASH_16MB_BOUN            0x1000000
+#define CMD_READ_CONFIG                        0x35
+#define CMD_FLAG_STATUS                        0x70
 
-/* Manufacture ID's */
-#define SPI_FLASH_SPANSION_IDCODE0     0x01
-#define SPI_FLASH_STMICRO_IDCODE0      0x20
-#define SPI_FLASH_WINBOND_IDCODE0      0xef
+/* Read commands */
+#define CMD_READ_ARRAY_SLOW            0x03
+#define CMD_READ_ARRAY_FAST            0x0b
+#define CMD_READ_ID                    0x9f
 
-#ifdef CONFIG_SPI_FLASH_BAR
 /* Bank addr access commands */
+#ifdef CONFIG_SPI_FLASH_BAR
 # define CMD_BANKADDR_BRWR             0x17
 # define CMD_BANKADDR_BRRD             0x16
 # define CMD_EXTNADDR_WREAR            0xC5
 #define STATUS_WIP                     0x01
 #define STATUS_PEC                     0x80
 
+/* Flash timeout values */
+#define SPI_FLASH_PROG_TIMEOUT         (2 * CONFIG_SYS_HZ)
+#define SPI_FLASH_PAGE_ERASE_TIMEOUT   (5 * CONFIG_SYS_HZ)
+#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ)
+
+/* SST specific */
+#ifdef CONFIG_SPI_FLASH_SST
+# define SST_WP                        0x01    /* Supports AAI word program */
+# define CMD_SST_BP            0x02    /* Byte Program */
+# define CMD_SST_AAI_WP                0xAD    /* Auto Address Incr Word Program */
+
+int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len,
+               const void *buf);
+#endif
+
 /* Send a single-byte command to the device and read the response */
 int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
 
@@ -58,9 +74,6 @@ int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
 int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
                size_t cmd_len, void *data, size_t data_len);
 
-int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
-               size_t len, void *data);
-
 /*
  * Send a multi-byte command to the device followed by (optional)
  * data. Used for programming the flash array, etc.
@@ -68,46 +81,34 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
 int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
                const void *data, size_t data_len);
 
-/*
- * Write the requested data out breaking it up into multiple write
- * commands as needed per the write size.
- */
-int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
-               size_t len, const void *buf);
 
-/*
- * Enable writing on the SPI flash.
- */
+/* Flash erase(sectors) operation, support all possible erase commands */
+int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len);
+
+/* Program the status register */
+int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr);
+
+/* Set quad enbale bit */
+int spi_flash_set_qeb(struct spi_flash *flash);
+
+/* Enable writing on the SPI flash */
 static inline int spi_flash_cmd_write_enable(struct spi_flash *flash)
 {
        return spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
 }
 
-/*
- * Disable writing on the SPI flash.
- */
+/* Disable writing on the SPI flash */
 static inline int spi_flash_cmd_write_disable(struct spi_flash *flash)
 {
        return spi_flash_cmd(flash->spi, CMD_WRITE_DISABLE, NULL, 0);
 }
 
-/* Program the status register. */
-int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr);
-
-#ifdef CONFIG_SPI_FLASH_BAR
-/* Program the bank address register */
-int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel);
-
-/* Configure the BAR - discover the bank cmds */
-int spi_flash_bank_config(struct spi_flash *flash, u8 idcode0);
-#endif
-
 /*
- * Same as spi_flash_cmd_read() except it also claims/releases the SPI
- * bus. Used as common part of the ->read() operation.
+ * Send the read status command to the device and wait for the wip
+ * (write-in-progress) bit to clear itself.
  */
-int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
-               size_t cmd_len, void *data, size_t data_len);
+int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout);
+
 /*
  * Used for spi_flash write operation
  * - SPI claim
@@ -120,21 +121,22 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
                size_t cmd_len, const void *buf, size_t buf_len);
 
 /*
- * Send the read status command to the device and wait for the wip
- * (write-in-progress) bit to clear itself.
+ * Flash write operation, support all possible write commands.
+ * Write the requested data out breaking it up into multiple write
+ * commands as needed per the write size.
  */
-int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout);
+int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
+               size_t len, const void *buf);
+
+/*
+ * Same as spi_flash_cmd_read() except it also claims/releases the SPI
+ * bus. Used as common part of the ->read() operation.
+ */
+int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
+               size_t cmd_len, void *data, size_t data_len);
+
+/* Flash read operation, support all possible read commands */
+int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
+               size_t len, void *data);
 
-/* Erase sectors. */
-int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
-
-/* Manufacturer-specific probe functions */
-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
-struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode);
+#endif /* _SPI_FLASH_INTERNAL_H_ */
diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
new file mode 100644 (file)
index 0000000..2396e22
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * SPI flash operations
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
+ * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <watchdog.h>
+
+#include "sf_internal.h"
+
+static void spi_flash_addr(u32 addr, u8 *cmd)
+{
+       /* cmd[0] is actual command */
+       cmd[1] = addr >> 16;
+       cmd[2] = addr >> 8;
+       cmd[3] = addr >> 0;
+}
+
+int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)
+{
+       u8 cmd;
+       int ret;
+
+       cmd = CMD_WRITE_STATUS;
+       ret = spi_flash_write_common(flash, &cmd, 1, &sr, 1);
+       if (ret < 0) {
+               debug("SF: fail to write status register\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_SPI_FLASH_BAR
+static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel)
+{
+       u8 cmd;
+       int ret;
+
+       if (flash->bank_curr == bank_sel) {
+               debug("SF: not require to enable bank%d\n", bank_sel);
+               return 0;
+       }
+
+       cmd = flash->bank_write_cmd;
+       ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1);
+       if (ret < 0) {
+               debug("SF: fail to write bank register\n");
+               return ret;
+       }
+       flash->bank_curr = bank_sel;
+
+       return 0;
+}
+#endif
+
+int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
+{
+       struct spi_slave *spi = flash->spi;
+       unsigned long timebase;
+       int ret;
+       u8 status;
+       u8 check_status = 0x0;
+       u8 poll_bit = STATUS_WIP;
+       u8 cmd = flash->poll_cmd;
+
+       if (cmd == CMD_FLAG_STATUS) {
+               poll_bit = STATUS_PEC;
+               check_status = poll_bit;
+       }
+
+       ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
+       if (ret) {
+               debug("SF: fail to read %s status register\n",
+                     cmd == CMD_READ_STATUS ? "read" : "flag");
+               return ret;
+       }
+
+       timebase = get_timer(0);
+       do {
+               WATCHDOG_RESET();
+
+               ret = spi_xfer(spi, 8, NULL, &status, 0);
+               if (ret)
+                       return -1;
+
+               if ((status & poll_bit) == check_status)
+                       break;
+
+       } while (get_timer(timebase) < timeout);
+
+       spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
+
+       if ((status & poll_bit) == check_status)
+               return 0;
+
+       /* Timed out */
+       debug("SF: time out!\n");
+       return -1;
+}
+
+int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
+               size_t cmd_len, const void *buf, size_t buf_len)
+{
+       struct spi_slave *spi = flash->spi;
+       unsigned long timeout = SPI_FLASH_PROG_TIMEOUT;
+       int ret;
+
+       if (buf == NULL)
+               timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT;
+
+       ret = spi_claim_bus(flash->spi);
+       if (ret) {
+               debug("SF: unable to claim SPI bus\n");
+               return ret;
+       }
+
+       ret = spi_flash_cmd_write_enable(flash);
+       if (ret < 0) {
+               debug("SF: enabling write failed\n");
+               return ret;
+       }
+
+       ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len);
+       if (ret < 0) {
+               debug("SF: write cmd failed\n");
+               return ret;
+       }
+
+       ret = spi_flash_cmd_wait_ready(flash, timeout);
+       if (ret < 0) {
+               debug("SF: write %s timed out\n",
+                     timeout == SPI_FLASH_PROG_TIMEOUT ?
+                       "program" : "page erase");
+               return ret;
+       }
+
+       spi_release_bus(spi);
+
+       return ret;
+}
+
+int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
+{
+       u32 erase_size;
+       u8 cmd[4];
+       int ret = -1;
+
+       erase_size = flash->erase_size;
+       if (offset % erase_size || len % erase_size) {
+               debug("SF: Erase offset/length not multiple of erase size\n");
+               return -1;
+       }
+
+       cmd[0] = flash->erase_cmd;
+       while (len) {
+#ifdef CONFIG_SPI_FLASH_BAR
+               u8 bank_sel;
+
+               bank_sel = offset / SPI_FLASH_16MB_BOUN;
+
+               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
+               if (ret) {
+                       debug("SF: fail to set bank%d\n", bank_sel);
+                       return ret;
+               }
+#endif
+               spi_flash_addr(offset, cmd);
+
+               debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+                     cmd[2], cmd[3], offset);
+
+               ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
+               if (ret < 0) {
+                       debug("SF: erase failed\n");
+                       break;
+               }
+
+               offset += erase_size;
+               len -= erase_size;
+       }
+
+       return ret;
+}
+
+int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
+               size_t len, const void *buf)
+{
+       unsigned long byte_addr, page_size;
+       size_t chunk_len, actual;
+       u8 cmd[4];
+       int ret = -1;
+
+       page_size = flash->page_size;
+
+       cmd[0] = CMD_PAGE_PROGRAM;
+       for (actual = 0; actual < len; actual += chunk_len) {
+#ifdef CONFIG_SPI_FLASH_BAR
+               u8 bank_sel;
+
+               bank_sel = offset / SPI_FLASH_16MB_BOUN;
+
+               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
+               if (ret) {
+                       debug("SF: fail to set bank%d\n", bank_sel);
+                       return ret;
+               }
+#endif
+               byte_addr = offset % page_size;
+               chunk_len = min(len - actual, page_size - byte_addr);
+
+               if (flash->spi->max_write_size)
+                       chunk_len = min(chunk_len, flash->spi->max_write_size);
+
+               spi_flash_addr(offset, cmd);
+
+               debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+                     buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+
+               ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
+                                       buf + actual, chunk_len);
+               if (ret < 0) {
+                       debug("SF: write failed\n");
+                       break;
+               }
+
+               offset += chunk_len;
+       }
+
+       return ret;
+}
+
+int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
+               size_t cmd_len, void *data, size_t data_len)
+{
+       struct spi_slave *spi = flash->spi;
+       int ret;
+
+       ret = spi_claim_bus(flash->spi);
+       if (ret) {
+               debug("SF: unable to claim SPI bus\n");
+               return ret;
+       }
+
+       ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len);
+       if (ret < 0) {
+               debug("SF: read cmd failed\n");
+               return ret;
+       }
+
+       spi_release_bus(spi);
+
+       return ret;
+}
+
+int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
+               size_t len, void *data)
+{
+       u8 cmd[5], bank_sel = 0;
+       u32 remain_len, read_len;
+       int ret = -1;
+
+       /* Handle memory-mapped SPI */
+       if (flash->memory_map) {
+               spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP);
+               memcpy(data, flash->memory_map + offset, len);
+               spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP_END);
+               return 0;
+       }
+
+       cmd[0] = CMD_READ_ARRAY_FAST;
+       cmd[4] = 0x00;
+
+       while (len) {
+#ifdef CONFIG_SPI_FLASH_BAR
+               bank_sel = offset / SPI_FLASH_16MB_BOUN;
+
+               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
+               if (ret) {
+                       debug("SF: fail to set bank%d\n", bank_sel);
+                       return ret;
+               }
+#endif
+               remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1) - offset);
+               if (len < remain_len)
+                       read_len = len;
+               else
+                       read_len = remain_len;
+
+               spi_flash_addr(offset, cmd);
+
+               ret = spi_flash_read_common(flash, cmd, sizeof(cmd),
+                                                       data, read_len);
+               if (ret < 0) {
+                       debug("SF: read failed\n");
+                       break;
+               }
+
+               offset += read_len;
+               len -= read_len;
+               data += read_len;
+       }
+
+       return ret;
+}
+
+#ifdef CONFIG_SPI_FLASH_SST
+static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
+{
+       int ret;
+       u8 cmd[4] = {
+               CMD_SST_BP,
+               offset >> 16,
+               offset >> 8,
+               offset,
+       };
+
+       debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
+             spi_w8r8(flash->spi, CMD_READ_STATUS), buf, cmd[0], offset);
+
+       ret = spi_flash_cmd_write_enable(flash);
+       if (ret)
+               return ret;
+
+       ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1);
+       if (ret)
+               return ret;
+
+       return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+}
+
+int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len,
+               const void *buf)
+{
+       size_t actual, cmd_len;
+       int ret;
+       u8 cmd[4];
+
+       ret = spi_claim_bus(flash->spi);
+       if (ret) {
+               debug("SF: Unable to claim SPI bus\n");
+               return ret;
+       }
+
+       /* If the data is not word aligned, write out leading single byte */
+       actual = offset % 2;
+       if (actual) {
+               ret = sst_byte_write(flash, offset, buf);
+               if (ret)
+                       goto done;
+       }
+       offset += actual;
+
+       ret = spi_flash_cmd_write_enable(flash);
+       if (ret)
+               goto done;
+
+       cmd_len = 4;
+       cmd[0] = CMD_SST_AAI_WP;
+       cmd[1] = offset >> 16;
+       cmd[2] = offset >> 8;
+       cmd[3] = offset;
+
+       for (; actual < len - 1; actual += 2) {
+               debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
+                     spi_w8r8(flash->spi, CMD_READ_STATUS), buf + actual,
+                     cmd[0], offset);
+
+               ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len,
+                                       buf + actual, 2);
+               if (ret) {
+                       debug("SF: sst word program failed\n");
+                       break;
+               }
+
+               ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+               if (ret)
+                       break;
+
+               cmd_len = 1;
+               offset += 2;
+       }
+
+       if (!ret)
+               ret = spi_flash_cmd_write_disable(flash);
+
+       /* If there is a single trailing byte, write it out */
+       if (!ret && actual != len)
+               ret = sst_byte_write(flash, offset, buf + actual);
+
+ done:
+       debug("SF: sst: program %s %zu bytes @ 0x%zx\n",
+             ret ? "failure" : "success", len, offset - actual);
+
+       spi_release_bus(flash->spi);
+       return ret;
+}
+#endif
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
new file mode 100644 (file)
index 0000000..4251b1b
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * SPI flash probing
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
+ * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <spi.h>
+#include <spi_flash.h>
+
+#include "sf_internal.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * struct spi_flash_params - SPI/QSPI flash device params structure
+ *
+ * @name:              Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
+ * @jedec:             Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
+ * @ext_jedec:         Device ext_jedec ID
+ * @sector_size:       Sector size of this device
+ * @nr_sectors:        No.of sectors on this device
+ * @flags:             Importent param, for flash specific behaviour
+ */
+struct spi_flash_params {
+       const char *name;
+       u32 jedec;
+       u16 ext_jedec;
+       u32 sector_size;
+       u32 nr_sectors;
+       u16 flags;
+};
+
+static const struct spi_flash_params spi_flash_params_table[] = {
+#ifdef CONFIG_SPI_FLASH_ATMEL          /* ATMEL */
+       {"AT45DB011D",     0x1f2200, 0x0,       64 * 1024,     4,              SECT_4K},
+       {"AT45DB021D",     0x1f2300, 0x0,       64 * 1024,     8,              SECT_4K},
+       {"AT45DB041D",     0x1f2400, 0x0,       64 * 1024,     8,              SECT_4K},
+       {"AT45DB081D",     0x1f2500, 0x0,       64 * 1024,    16,              SECT_4K},
+       {"AT45DB161D",     0x1f2600, 0x0,       64 * 1024,    32,              SECT_4K},
+       {"AT45DB321D",     0x1f2700, 0x0,       64 * 1024,    64,              SECT_4K},
+       {"AT45DB641D",     0x1f2800, 0x0,       64 * 1024,   128,              SECT_4K},
+#endif
+#ifdef CONFIG_SPI_FLASH_EON            /* EON */
+       {"EN25Q32B",       0x1c3016, 0x0,       64 * 1024,    64,                    0},
+       {"EN25Q64",        0x1c3017, 0x0,       64 * 1024,   128,              SECT_4K},
+       {"EN25Q128B",      0x1c3018, 0x0,       64 * 1024,   256,                    0},
+       {"EN25S64",        0x1c3817, 0x0,       64 * 1024,   128,                    0},
+#endif
+#ifdef CONFIG_SPI_FLASH_GIGADEVICE     /* GIGADEVICE */
+       {"GD25Q64B",       0xc84017, 0x0,       64 * 1024,   128,              SECT_4K},
+       {"GD25LQ32",       0xc86016, 0x0,       64 * 1024,    64,              SECT_4K},
+#endif
+#ifdef CONFIG_SPI_FLASH_MACRONIX       /* MACRONIX */
+       {"MX25L4005",      0xc22013, 0x0,       64 * 1024,     8,                    0},
+       {"MX25L8005",      0xc22014, 0x0,       64 * 1024,    16,                    0},
+       {"MX25L1605D",     0xc22015, 0x0,       64 * 1024,    32,                    0},
+       {"MX25L3205D",     0xc22016, 0x0,       64 * 1024,    64,                    0},
+       {"MX25L6405D",     0xc22017, 0x0,       64 * 1024,   128,                    0},
+       {"MX25L12805",     0xc22018, 0x0,       64 * 1024,   256,                    0},
+       {"MX25L25635F",    0xc22019, 0x0,       64 * 1024,   512,                    0},
+       {"MX25L51235F",    0xc2201A, 0x0,       64 * 1024,  1024,                    0},
+       {"MX25L12855E",    0xc22618, 0x0,       64 * 1024,   256,                    0},
+#endif
+#ifdef CONFIG_SPI_FLASH_SPANSION       /* SPANSION */
+       {"S25FL008A",      0x010213, 0x0,       64 * 1024,    16,                    0},
+       {"S25FL016A",      0x010214, 0x0,       64 * 1024,    32,                    0},
+       {"S25FL032A",      0x010215, 0x0,       64 * 1024,    64,                    0},
+       {"S25FL064A",      0x010216, 0x0,       64 * 1024,   128,                    0},
+       {"S25FL128P_256K", 0x012018, 0x0300,   256 * 1024,    64,                    0},
+       {"S25FL128P_64K",  0x012018, 0x0301,    64 * 1024,   256,                    0},
+       {"S25FL032P",      0x010215, 0x4d00,    64 * 1024,    64,                    0},
+       {"S25FL064P",      0x010216, 0x4d00,    64 * 1024,   128,                    0},
+       {"S25FL128S_64K",  0x012018, 0x4d01,    64 * 1024,   256,                    0},
+       {"S25FL256S_256K", 0x010219, 0x4d00,    64 * 1024,   512,                    0},
+       {"S25FL256S_64K",  0x010219, 0x4d01,    64 * 1024,   512,                    0},
+       {"S25FL512S_256K", 0x010220, 0x4d00,    64 * 1024,  1024,                    0},
+       {"S25FL512S_64K",  0x010220, 0x4d01,    64 * 1024,  1024,                    0},
+#endif
+#ifdef CONFIG_SPI_FLASH_STMICRO                /* STMICRO */
+       {"M25P10",         0x202011, 0x0,       32 * 1024,     4,                    0},
+       {"M25P20",         0x202012, 0x0,       64 * 1024,     4,                    0},
+       {"M25P40",         0x202013, 0x0,       64 * 1024,     8,                    0},
+       {"M25P80",         0x202014, 0x0,       64 * 1024,    16,                    0},
+       {"M25P16",         0x202015, 0x0,       64 * 1024,    32,                    0},
+       {"M25P32",         0x202016, 0x0,       64 * 1024,    64,                    0},
+       {"M25P64",         0x202017, 0x0,       64 * 1024,   128,                    0},
+       {"M25P128",        0x202018, 0x0,      256 * 1024,    64,                    0},
+       {"N25Q32",         0x20ba16, 0x0,       64 * 1024,    64,              SECT_4K},
+       {"N25Q32A",        0x20bb16, 0x0,       64 * 1024,    64,              SECT_4K},
+       {"N25Q64",         0x20ba17, 0x0,       64 * 1024,   128,              SECT_4K},
+       {"N25Q64A",        0x20bb17, 0x0,       64 * 1024,   128,              SECT_4K},
+       {"N25Q128",        0x20ba18, 0x0,       64 * 1024,   256,              SECT_4K},
+       {"N25Q128A",       0x20bb18, 0x0,       64 * 1024,   256,              SECT_4K},
+       {"N25Q256",        0x20ba19, 0x0,       64 * 1024,   512,              SECT_4K},
+       {"N25Q256A",       0x20bb19, 0x0,       64 * 1024,   512,              SECT_4K},
+       {"N25Q512",        0x20ba20, 0x0,       64 * 1024,  1024,      E_FSR | SECT_4K},
+       {"N25Q512A",       0x20bb20, 0x0,       64 * 1024,  1024,      E_FSR | SECT_4K},
+       {"N25Q1024",       0x20ba21, 0x0,       64 * 1024,  2048,      E_FSR | SECT_4K},
+       {"N25Q1024A",      0x20bb21, 0x0,       64 * 1024,  2048,      E_FSR | SECT_4K},
+#endif
+#ifdef CONFIG_SPI_FLASH_SST            /* SST */
+       {"SST25VF040B",    0xbf258d, 0x0,       64 * 1024,     8,     SECT_4K | SST_WP},
+       {"SST25VF080B",    0xbf258e, 0x0,       64 * 1024,    16,     SECT_4K | SST_WP},
+       {"SST25VF016B",    0xbf2541, 0x0,       64 * 1024,    32,     SECT_4K | SST_WP},
+       {"SST25VF032B",    0xbf254a, 0x0,       64 * 1024,    64,     SECT_4K | SST_WP},
+       {"SST25VF064C",    0xbf254b, 0x0,       64 * 1024,   128,              SECT_4K},
+       {"SST25WF512",     0xbf2501, 0x0,       64 * 1024,     1,     SECT_4K | SST_WP},
+       {"SST25WF010",     0xbf2502, 0x0,       64 * 1024,     2,     SECT_4K | SST_WP},
+       {"SST25WF020",     0xbf2503, 0x0,       64 * 1024,     4,     SECT_4K | SST_WP},
+       {"SST25WF040",     0xbf2504, 0x0,       64 * 1024,     8,     SECT_4K | SST_WP},
+       {"SST25WF080",     0xbf2505, 0x0,       64 * 1024,    16,     SECT_4K | SST_WP},
+#endif
+#ifdef CONFIG_SPI_FLASH_WINBOND                /* WINBOND */
+       {"W25P80",         0xef2014, 0x0,       64 * 1024,    16,                   0},
+       {"W25P16",         0xef2015, 0x0,       64 * 1024,    32,                   0},
+       {"W25P32",         0xef2016, 0x0,       64 * 1024,    64,                   0},
+       {"W25X40",         0xef3013, 0x0,       64 * 1024,     8,             SECT_4K},
+       {"W25X16",         0xef3015, 0x0,       64 * 1024,    32,             SECT_4K},
+       {"W25X32",         0xef3016, 0x0,       64 * 1024,    64,             SECT_4K},
+       {"W25X64",         0xef3017, 0x0,       64 * 1024,   128,             SECT_4K},
+       {"W25Q80BL",       0xef4014, 0x0,       64 * 1024,    16,             SECT_4K},
+       {"W25Q16CL",       0xef4015, 0x0,       64 * 1024,    32,             SECT_4K},
+       {"W25Q32BV",       0xef4016, 0x0,       64 * 1024,    64,             SECT_4K},
+       {"W25Q64CV",       0xef4017, 0x0,       64 * 1024,   128,             SECT_4K},
+       {"W25Q128BV",      0xef4018, 0x0,       64 * 1024,   256,             SECT_4K},
+       {"W25Q256",        0xef4019, 0x0,       64 * 1024,   512,             SECT_4K},
+       {"W25Q80BW",       0xef5014, 0x0,       64 * 1024,    16,             SECT_4K},
+       {"W25Q16DW",       0xef6015, 0x0,       64 * 1024,    32,             SECT_4K},
+       {"W25Q32DW",       0xef6016, 0x0,       64 * 1024,    64,             SECT_4K},
+       {"W25Q64DW",       0xef6017, 0x0,       64 * 1024,   128,             SECT_4K},
+       {"W25Q128FW",      0xef6018, 0x0,       64 * 1024,   256,             SECT_4K},
+#endif
+       /*
+        * Note:
+        * Below paired flash devices has similar spi_flash_params params.
+        * (S25FL129P_64K, S25FL128S_64K)
+        * (W25Q80BL, W25Q80BV)
+        * (W25Q16CL, W25Q16DV)
+        * (W25Q32BV, W25Q32FV_SPI)
+        * (W25Q64CV, W25Q64FV_SPI)
+        * (W25Q128BV, W25Q128FV_SPI)
+        * (W25Q32DW, W25Q32FV_QPI)
+        * (W25Q64DW, W25Q64FV_QPI)
+        * (W25Q128FW, W25Q128FV_QPI)
+        */
+};
+
+static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
+               u8 *idcode)
+{
+       const struct spi_flash_params *params;
+       struct spi_flash *flash;
+       int i;
+       u16 jedec = idcode[1] << 8 | idcode[2];
+       u16 ext_jedec = idcode[3] << 8 | idcode[4];
+
+       /* Get the flash id (jedec = manuf_id + dev_id, ext_jedec) */
+       for (i = 0; i < ARRAY_SIZE(spi_flash_params_table); i++) {
+               params = &spi_flash_params_table[i];
+               if ((params->jedec >> 16) == idcode[0]) {
+                       if ((params->jedec & 0xFFFF) == jedec) {
+                               if (params->ext_jedec == 0)
+                                       break;
+                               else if (params->ext_jedec == ext_jedec)
+                                       break;
+                       }
+               }
+       }
+
+       if (i == ARRAY_SIZE(spi_flash_params_table)) {
+               printf("SF: Unsupported flash IDs: ");
+               printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
+                      idcode[0], jedec, ext_jedec);
+               return NULL;
+       }
+
+       flash = malloc(sizeof(*flash));
+       if (!flash) {
+               debug("SF: Failed to allocate spi_flash\n");
+               return NULL;
+       }
+       memset(flash, '\0', sizeof(*flash));
+
+       flash->spi = spi;
+       flash->name = params->name;
+       flash->memory_map = spi->memory_map;
+
+       /* Assign spi_flash ops */
+       flash->write = spi_flash_cmd_write_ops;
+#ifdef CONFIG_SPI_FLASH_SST
+       if (params->flags & SST_WP)
+               flash->write = sst_write_wp;
+#endif
+       flash->erase = spi_flash_cmd_erase_ops;
+       flash->read = spi_flash_cmd_read_ops;
+
+       /* Compute the flash size */
+       flash->page_size = (ext_jedec == 0x4d00) ? 512 : 256;
+       flash->sector_size = params->sector_size;
+       flash->size = flash->sector_size * params->nr_sectors;
+
+       /* Compute erase sector and command */
+       if (params->flags & SECT_4K) {
+               flash->erase_cmd = CMD_ERASE_4K;
+               flash->erase_size = 4096;
+       } else if (params->flags & SECT_32K) {
+               flash->erase_cmd = CMD_ERASE_32K;
+               flash->erase_size = 32768;
+       } else {
+               flash->erase_cmd = CMD_ERASE_64K;
+               flash->erase_size = flash->sector_size;
+       }
+
+       /* Poll cmd seclection */
+       flash->poll_cmd = CMD_READ_STATUS;
+#ifdef CONFIG_SPI_FLASH_STMICRO
+       if (params->flags & E_FSR)
+               flash->poll_cmd = CMD_FLAG_STATUS;
+#endif
+
+       /* Configure the BAR - discover bank cmds and read current bank */
+#ifdef CONFIG_SPI_FLASH_BAR
+       u8 curr_bank = 0;
+       if (flash->size > SPI_FLASH_16MB_BOUN) {
+               flash->bank_read_cmd = (idcode[0] == 0x01) ?
+                                       CMD_BANKADDR_BRRD : CMD_EXTNADDR_RDEAR;
+               flash->bank_write_cmd = (idcode[0] == 0x01) ?
+                                       CMD_BANKADDR_BRWR : CMD_EXTNADDR_WREAR;
+
+               if (spi_flash_read_common(flash, &flash->bank_read_cmd, 1,
+                                         &curr_bank, 1)) {
+                       debug("SF: fail to read bank addr register\n");
+                       return NULL;
+               }
+               flash->bank_curr = curr_bank;
+       } else {
+               flash->bank_curr = curr_bank;
+       }
+#endif
+
+       /* Flash powers up read-only, so clear BP# bits */
+#if defined(CONFIG_SPI_FLASH_ATMEL) || \
+       defined(CONFIG_SPI_FLASH_MACRONIX) || \
+       defined(CONFIG_SPI_FLASH_SST)
+               spi_flash_cmd_write_status(flash, 0);
+#endif
+
+       return flash;
+}
+
+#ifdef CONFIG_OF_CONTROL
+int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
+{
+       fdt_addr_t addr;
+       fdt_size_t size;
+       int node;
+
+       /* If there is no node, do nothing */
+       node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
+       if (node < 0)
+               return 0;
+
+       addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
+       if (addr == FDT_ADDR_T_NONE) {
+               debug("%s: Cannot decode address\n", __func__);
+               return 0;
+       }
+
+       if (flash->size != size) {
+               debug("%s: Memory map must cover entire device\n", __func__);
+               return -1;
+       }
+       flash->memory_map = (void *)addr;
+
+       return 0;
+}
+#endif /* CONFIG_OF_CONTROL */
+
+struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int spi_mode)
+{
+       struct spi_slave *spi;
+       struct spi_flash *flash = NULL;
+       u8 idcode[5];
+       int ret;
+
+       /* Setup spi_slave */
+       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+       if (!spi) {
+               printf("SF: Failed to set up slave\n");
+               return NULL;
+       }
+
+       /* Claim spi bus */
+       ret = spi_claim_bus(spi);
+       if (ret) {
+               debug("SF: Failed to claim SPI bus: %d\n", ret);
+               goto err_claim_bus;
+       }
+
+       /* Read the ID codes */
+       ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
+       if (ret) {
+               printf("SF: Failed to get idcodes\n");
+               goto err_read_id;
+       }
+
+#ifdef DEBUG
+       printf("SF: Got idcodes\n");
+       print_buffer(0, idcode, 1, sizeof(idcode), 0);
+#endif
+
+       /* Validate params from spi_flash_params table */
+       flash = spi_flash_validate_params(spi, idcode);
+       if (!flash)
+               goto err_read_id;
+
+#ifdef CONFIG_OF_CONTROL
+       if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
+               debug("SF: FDT decode error\n");
+               goto err_read_id;
+       }
+#endif
+#ifndef CONFIG_SPL_BUILD
+       printf("SF: Detected %s with page size ", flash->name);
+       print_size(flash->page_size, ", erase size ");
+       print_size(flash->erase_size, ", total ");
+       print_size(flash->size, "");
+       if (flash->memory_map)
+               printf(", mapped at %p", flash->memory_map);
+       puts("\n");
+#endif
+#ifndef CONFIG_SPI_FLASH_BAR
+       if (flash->size > SPI_FLASH_16MB_BOUN) {
+               puts("SF: Warning - Only lower 16MiB accessible,");
+               puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
+       }
+#endif
+
+       /* Release spi bus */
+       spi_release_bus(spi);
+
+       return flash;
+
+err_read_id:
+       spi_release_bus(spi);
+err_claim_bus:
+       spi_free_slave(spi);
+       return NULL;
+}
+
+void spi_flash_free(struct spi_flash *flash)
+{
+       spi_free_slave(flash->spi);
+       free(flash);
+}
diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c
deleted file mode 100644 (file)
index fa7ac8c..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2009 Freescale Semiconductor, Inc.
- *
- * Author: Mingkai Hu (Mingkai.hu@freescale.com)
- * Based on stmicro.c by Wolfgang Denk (wd@denx.de),
- * TsiChung Liew (Tsi-Chung.Liew@freescale.com),
- * and  Jason McMullan (mcmullan@netapp.com)
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-struct spansion_spi_flash_params {
-       u16 idcode1;
-       u16 idcode2;
-       u16 pages_per_sector;
-       u16 nr_sectors;
-       const char *name;
-};
-
-static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
-       {
-               .idcode1 = 0x0213,
-               .idcode2 = 0,
-               .pages_per_sector = 256,
-               .nr_sectors = 16,
-               .name = "S25FL008A",
-       },
-       {
-               .idcode1 = 0x0214,
-               .idcode2 = 0,
-               .pages_per_sector = 256,
-               .nr_sectors = 32,
-               .name = "S25FL016A",
-       },
-       {
-               .idcode1 = 0x0215,
-               .idcode2 = 0,
-               .pages_per_sector = 256,
-               .nr_sectors = 64,
-               .name = "S25FL032A",
-       },
-       {
-               .idcode1 = 0x0216,
-               .idcode2 = 0,
-               .pages_per_sector = 256,
-               .nr_sectors = 128,
-               .name = "S25FL064A",
-       },
-       {
-               .idcode1 = 0x2018,
-               .idcode2 = 0x0301,
-               .pages_per_sector = 256,
-               .nr_sectors = 256,
-               .name = "S25FL128P_64K",
-       },
-       {
-               .idcode1 = 0x2018,
-               .idcode2 = 0x0300,
-               .pages_per_sector = 1024,
-               .nr_sectors = 64,
-               .name = "S25FL128P_256K",
-       },
-       {
-               .idcode1 = 0x0215,
-               .idcode2 = 0x4d00,
-               .pages_per_sector = 256,
-               .nr_sectors = 64,
-               .name = "S25FL032P",
-       },
-       {
-               .idcode1 = 0x0216,
-               .idcode2 = 0x4d00,
-               .pages_per_sector = 256,
-               .nr_sectors = 128,
-               .name = "S25FL064P",
-       },
-       {
-               .idcode1 = 0x2018,
-               .idcode2 = 0x4d01,
-               .pages_per_sector = 256,
-               .nr_sectors = 256,
-               .name = "S25FL129P_64K/S25FL128S_64K",
-       },
-       {
-               .idcode1 = 0x0219,
-               .idcode2 = 0x4d01,
-               .pages_per_sector = 256,
-               .nr_sectors = 512,
-               .name = "S25FL256S_64K",
-       },
-       {
-               .idcode1 = 0x0220,
-               .idcode2 = 0x4d01,
-               .pages_per_sector = 256,
-               .nr_sectors = 1024,
-               .name = "S25FL512S_64K",
-       },
-};
-
-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
-{
-       const struct spansion_spi_flash_params *params;
-       struct spi_flash *flash;
-       unsigned int i;
-       unsigned short jedec, ext_jedec;
-
-       jedec = idcode[1] << 8 | idcode[2];
-       ext_jedec = idcode[3] << 8 | idcode[4];
-
-       for (i = 0; i < ARRAY_SIZE(spansion_spi_flash_table); i++) {
-               params = &spansion_spi_flash_table[i];
-               if (params->idcode1 == jedec) {
-                       if (params->idcode2 == ext_jedec)
-                               break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(spansion_spi_flash_table)) {
-               debug("SF: Unsupported SPANSION ID %04x %04x\n",
-                     jedec, ext_jedec);
-               return NULL;
-       }
-
-       flash = spi_flash_alloc_base(spi, params->name);
-       if (!flash) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-
-       flash->page_size = 256;
-       flash->sector_size = 256 * params->pages_per_sector;
-       flash->size = flash->sector_size * params->nr_sectors;
-
-       return flash;
-}
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
deleted file mode 100644 (file)
index 5d5055f..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * SPI flash interface
- *
- * Copyright (C) 2008 Atmel Corporation
- * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <fdtdec.h>
-#include <malloc.h>
-#include <spi.h>
-#include <spi_flash.h>
-#include <watchdog.h>
-
-#include "spi_flash_internal.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static void spi_flash_addr(u32 addr, u8 *cmd)
-{
-       /* cmd[0] is actual command */
-       cmd[1] = addr >> 16;
-       cmd[2] = addr >> 8;
-       cmd[3] = addr >> 0;
-}
-
-static int spi_flash_read_write(struct spi_slave *spi,
-                               const u8 *cmd, size_t cmd_len,
-                               const u8 *data_out, u8 *data_in,
-                               size_t data_len)
-{
-       unsigned long flags = SPI_XFER_BEGIN;
-       int ret;
-
-       if (data_len == 0)
-               flags |= SPI_XFER_END;
-
-       ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
-       if (ret) {
-               debug("SF: Failed to send command (%zu bytes): %d\n",
-                     cmd_len, ret);
-       } else if (data_len != 0) {
-               ret = spi_xfer(spi, data_len * 8, data_out, data_in,
-                                       SPI_XFER_END);
-               if (ret)
-                       debug("SF: Failed to transfer %zu bytes of data: %d\n",
-                             data_len, ret);
-       }
-
-       return ret;
-}
-
-int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len)
-{
-       return spi_flash_cmd_read(spi, &cmd, 1, response, len);
-}
-
-int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
-               size_t cmd_len, void *data, size_t data_len)
-{
-       return spi_flash_read_write(spi, cmd, cmd_len, NULL, data, data_len);
-}
-
-int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
-               const void *data, size_t data_len)
-{
-       return spi_flash_read_write(spi, cmd, cmd_len, data, NULL, data_len);
-}
-
-int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
-{
-       struct spi_slave *spi = flash->spi;
-       unsigned long timebase;
-       int ret;
-       u8 status;
-       u8 check_status = 0x0;
-       u8 poll_bit = STATUS_WIP;
-       u8 cmd = flash->poll_cmd;
-
-       if (cmd == CMD_FLAG_STATUS) {
-               poll_bit = STATUS_PEC;
-               check_status = poll_bit;
-       }
-
-       ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
-       if (ret) {
-               debug("SF: fail to read %s status register\n",
-                     cmd == CMD_READ_STATUS ? "read" : "flag");
-               return ret;
-       }
-
-       timebase = get_timer(0);
-       do {
-               WATCHDOG_RESET();
-
-               ret = spi_xfer(spi, 8, NULL, &status, 0);
-               if (ret)
-                       return -1;
-
-               if ((status & poll_bit) == check_status)
-                       break;
-
-       } while (get_timer(timebase) < timeout);
-
-       spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
-
-       if ((status & poll_bit) == check_status)
-               return 0;
-
-       /* Timed out */
-       debug("SF: time out!\n");
-       return -1;
-}
-
-int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
-               size_t cmd_len, const void *buf, size_t buf_len)
-{
-       struct spi_slave *spi = flash->spi;
-       unsigned long timeout = SPI_FLASH_PROG_TIMEOUT;
-       int ret;
-
-       if (buf == NULL)
-               timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT;
-
-       ret = spi_claim_bus(flash->spi);
-       if (ret) {
-               debug("SF: unable to claim SPI bus\n");
-               return ret;
-       }
-
-       ret = spi_flash_cmd_write_enable(flash);
-       if (ret < 0) {
-               debug("SF: enabling write failed\n");
-               return ret;
-       }
-
-       ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len);
-       if (ret < 0) {
-               debug("SF: write cmd failed\n");
-               return ret;
-       }
-
-       ret = spi_flash_cmd_wait_ready(flash, timeout);
-       if (ret < 0) {
-               debug("SF: write %s timed out\n",
-                     timeout == SPI_FLASH_PROG_TIMEOUT ?
-                       "program" : "page erase");
-               return ret;
-       }
-
-       spi_release_bus(spi);
-
-       return ret;
-}
-
-int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
-{
-       u32 erase_size;
-       u8 cmd[4];
-       int ret = -1;
-
-       erase_size = flash->sector_size;
-       if (offset % erase_size || len % erase_size) {
-               debug("SF: Erase offset/length not multiple of erase size\n");
-               return -1;
-       }
-
-       if (erase_size == 4096)
-               cmd[0] = CMD_ERASE_4K;
-       else
-               cmd[0] = CMD_ERASE_64K;
-
-       while (len) {
-#ifdef CONFIG_SPI_FLASH_BAR
-               u8 bank_sel;
-
-               bank_sel = offset / SPI_FLASH_16MB_BOUN;
-
-               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
-               if (ret) {
-                       debug("SF: fail to set bank%d\n", bank_sel);
-                       return ret;
-               }
-#endif
-               spi_flash_addr(offset, cmd);
-
-               debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
-                     cmd[2], cmd[3], offset);
-
-               ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
-               if (ret < 0) {
-                       debug("SF: erase failed\n");
-                       break;
-               }
-
-               offset += erase_size;
-               len -= erase_size;
-       }
-
-       return ret;
-}
-
-int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
-               size_t len, const void *buf)
-{
-       unsigned long byte_addr, page_size;
-       size_t chunk_len, actual;
-       u8 cmd[4];
-       int ret = -1;
-
-       page_size = flash->page_size;
-
-       cmd[0] = CMD_PAGE_PROGRAM;
-       for (actual = 0; actual < len; actual += chunk_len) {
-#ifdef CONFIG_SPI_FLASH_BAR
-               u8 bank_sel;
-
-               bank_sel = offset / SPI_FLASH_16MB_BOUN;
-
-               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
-               if (ret) {
-                       debug("SF: fail to set bank%d\n", bank_sel);
-                       return ret;
-               }
-#endif
-               byte_addr = offset % page_size;
-               chunk_len = min(len - actual, page_size - byte_addr);
-
-               if (flash->spi->max_write_size)
-                       chunk_len = min(chunk_len, flash->spi->max_write_size);
-
-               spi_flash_addr(offset, cmd);
-
-               debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
-                     buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
-
-               ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
-                                       buf + actual, chunk_len);
-               if (ret < 0) {
-                       debug("SF: write failed\n");
-                       break;
-               }
-
-               offset += chunk_len;
-       }
-
-       return ret;
-}
-
-int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
-               size_t cmd_len, void *data, size_t data_len)
-{
-       struct spi_slave *spi = flash->spi;
-       int ret;
-
-       ret = spi_claim_bus(flash->spi);
-       if (ret) {
-               debug("SF: unable to claim SPI bus\n");
-               return ret;
-       }
-
-       ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len);
-       if (ret < 0) {
-               debug("SF: read cmd failed\n");
-               return ret;
-       }
-
-       spi_release_bus(spi);
-
-       return ret;
-}
-
-int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
-               size_t len, void *data)
-{
-       u8 cmd[5], bank_sel = 0;
-       u32 remain_len, read_len;
-       int ret = -1;
-
-       /* Handle memory-mapped SPI */
-       if (flash->memory_map) {
-               memcpy(data, flash->memory_map + offset, len);
-               return 0;
-       }
-
-       cmd[0] = CMD_READ_ARRAY_FAST;
-       cmd[4] = 0x00;
-
-       while (len) {
-#ifdef CONFIG_SPI_FLASH_BAR
-               bank_sel = offset / SPI_FLASH_16MB_BOUN;
-
-               ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
-               if (ret) {
-                       debug("SF: fail to set bank%d\n", bank_sel);
-                       return ret;
-               }
-#endif
-               remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1) - offset);
-               if (len < remain_len)
-                       read_len = len;
-               else
-                       read_len = remain_len;
-
-               spi_flash_addr(offset, cmd);
-
-               ret = spi_flash_read_common(flash, cmd, sizeof(cmd),
-                                                       data, read_len);
-               if (ret < 0) {
-                       debug("SF: read failed\n");
-                       break;
-               }
-
-               offset += read_len;
-               len -= read_len;
-               data += read_len;
-       }
-
-       return ret;
-}
-
-int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)
-{
-       u8 cmd;
-       int ret;
-
-       cmd = CMD_WRITE_STATUS;
-       ret = spi_flash_write_common(flash, &cmd, 1, &sr, 1);
-       if (ret < 0) {
-               debug("SF: fail to write status register\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-#ifdef CONFIG_SPI_FLASH_BAR
-int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel)
-{
-       u8 cmd;
-       int ret;
-
-       if (flash->bank_curr == bank_sel) {
-               debug("SF: not require to enable bank%d\n", bank_sel);
-               return 0;
-       }
-
-       cmd = flash->bank_write_cmd;
-       ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1);
-       if (ret < 0) {
-               debug("SF: fail to write bank register\n");
-               return ret;
-       }
-       flash->bank_curr = bank_sel;
-
-       return 0;
-}
-
-int spi_flash_bank_config(struct spi_flash *flash, u8 idcode0)
-{
-       u8 cmd;
-       u8 curr_bank = 0;
-
-       /* discover bank cmds */
-       switch (idcode0) {
-       case SPI_FLASH_SPANSION_IDCODE0:
-               flash->bank_read_cmd = CMD_BANKADDR_BRRD;
-               flash->bank_write_cmd = CMD_BANKADDR_BRWR;
-               break;
-       case SPI_FLASH_STMICRO_IDCODE0:
-       case SPI_FLASH_WINBOND_IDCODE0:
-               flash->bank_read_cmd = CMD_EXTNADDR_RDEAR;
-               flash->bank_write_cmd = CMD_EXTNADDR_WREAR;
-               break;
-       default:
-               printf("SF: Unsupported bank commands %02x\n", idcode0);
-               return -1;
-       }
-
-       /* read the bank reg - on which bank the flash is in currently */
-       cmd = flash->bank_read_cmd;
-       if (flash->size > SPI_FLASH_16MB_BOUN) {
-               if (spi_flash_read_common(flash, &cmd, 1, &curr_bank, 1)) {
-                       debug("SF: fail to read bank addr register\n");
-                       return -1;
-               }
-               flash->bank_curr = curr_bank;
-       } else {
-               flash->bank_curr = curr_bank;
-       }
-
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_OF_CONTROL
-int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
-{
-       fdt_addr_t addr;
-       fdt_size_t size;
-       int node;
-
-       /* If there is no node, do nothing */
-       node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
-       if (node < 0)
-               return 0;
-
-       addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
-       if (addr == FDT_ADDR_T_NONE) {
-               debug("%s: Cannot decode address\n", __func__);
-               return 0;
-       }
-
-       if (flash->size != size) {
-               debug("%s: Memory map must cover entire device\n", __func__);
-               return -1;
-       }
-       flash->memory_map = (void *)addr;
-
-       return 0;
-}
-#endif /* CONFIG_OF_CONTROL */
-
-/*
- * The following table holds all device probe functions
- *
- * shift:  number of continuation bytes before the ID
- * idcode: the expected IDCODE or 0xff for non JEDEC devices
- * probe:  the function to call
- *
- * Non JEDEC devices should be ordered in the table such that
- * the probe functions with best detection algorithms come first.
- *
- * Several matching entries are permitted, they will be tried
- * in sequence until a probe function returns non NULL.
- *
- * IDCODE_CONT_LEN may be redefined if a device needs to declare a
- * larger "shift" value.  IDCODE_PART_LEN generally shouldn't be
- * changed.  This is the max number of bytes probe functions may
- * examine when looking up part-specific identification info.
- *
- * Probe functions will be given the idcode buffer starting at their
- * manu id byte (the "idcode" in the table below).  In other words,
- * all of the continuation bytes will be skipped (the "shift" below).
- */
-#define IDCODE_CONT_LEN 0
-#define IDCODE_PART_LEN 5
-static const struct {
-       const u8 shift;
-       const u8 idcode;
-       struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
-} flashes[] = {
-       /* Keep it sorted by define name */
-#ifdef CONFIG_SPI_FLASH_ATMEL
-       { 0, 0x1f, spi_flash_probe_atmel, },
-#endif
-#ifdef CONFIG_SPI_FLASH_EON
-       { 0, 0x1c, spi_flash_probe_eon, },
-#endif
-#ifdef CONFIG_SPI_FLASH_GIGADEVICE
-       { 0, 0xc8, spi_flash_probe_gigadevice, },
-#endif
-#ifdef CONFIG_SPI_FLASH_MACRONIX
-       { 0, 0xc2, spi_flash_probe_macronix, },
-#endif
-#ifdef CONFIG_SPI_FLASH_SPANSION
-       { 0, 0x01, spi_flash_probe_spansion, },
-#endif
-#ifdef CONFIG_SPI_FLASH_SST
-       { 0, 0xbf, spi_flash_probe_sst, },
-#endif
-#ifdef CONFIG_SPI_FLASH_STMICRO
-       { 0, 0x20, spi_flash_probe_stmicro, },
-#endif
-#ifdef CONFIG_SPI_FLASH_WINBOND
-       { 0, 0xef, spi_flash_probe_winbond, },
-#endif
-#ifdef CONFIG_SPI_FRAM_RAMTRON
-       { 6, 0xc2, spi_fram_probe_ramtron, },
-# undef IDCODE_CONT_LEN
-# define IDCODE_CONT_LEN 6
-#endif
-       /* Keep it sorted by best detection */
-#ifdef CONFIG_SPI_FLASH_STMICRO
-       { 0, 0xff, spi_flash_probe_stmicro, },
-#endif
-#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
-       { 0, 0xff, spi_fram_probe_ramtron, },
-#endif
-};
-#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
-
-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int spi_mode)
-{
-       struct spi_slave *spi;
-       struct spi_flash *flash = NULL;
-       int ret, i, shift;
-       u8 idcode[IDCODE_LEN], *idp;
-
-       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
-       if (!spi) {
-               printf("SF: Failed to set up slave\n");
-               return NULL;
-       }
-
-       ret = spi_claim_bus(spi);
-       if (ret) {
-               debug("SF: Failed to claim SPI bus: %d\n", ret);
-               goto err_claim_bus;
-       }
-
-       /* Read the ID codes */
-       ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
-       if (ret)
-               goto err_read_id;
-
-#ifdef DEBUG
-       printf("SF: Got idcodes\n");
-       print_buffer(0, idcode, 1, sizeof(idcode), 0);
-#endif
-
-       /* count the number of continuation bytes */
-       for (shift = 0, idp = idcode;
-            shift < IDCODE_CONT_LEN && *idp == 0x7f;
-            ++shift, ++idp)
-               continue;
-
-       /* search the table for matches in shift and id */
-       for (i = 0; i < ARRAY_SIZE(flashes); ++i)
-               if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
-                       /* we have a match, call probe */
-                       flash = flashes[i].probe(spi, idp);
-                       if (flash)
-                               break;
-               }
-
-       if (!flash) {
-               printf("SF: Unsupported manufacturer %02x\n", *idp);
-               goto err_manufacturer_probe;
-       }
-
-#ifdef CONFIG_SPI_FLASH_BAR
-       /* Configure the BAR - disover bank cmds and read current bank  */
-       ret = spi_flash_bank_config(flash, *idp);
-       if (ret < 0)
-               goto err_manufacturer_probe;
-#endif
-
-#ifdef CONFIG_OF_CONTROL
-       if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
-               debug("SF: FDT decode error\n");
-               goto err_manufacturer_probe;
-       }
-#endif
-#ifndef CONFIG_SPL_BUILD
-       printf("SF: Detected %s with page size ", flash->name);
-       print_size(flash->sector_size, ", total ");
-       print_size(flash->size, "");
-       if (flash->memory_map)
-               printf(", mapped at %p", flash->memory_map);
-       puts("\n");
-#endif
-#ifndef CONFIG_SPI_FLASH_BAR
-       if (flash->size > SPI_FLASH_16MB_BOUN) {
-               puts("SF: Warning - Only lower 16MiB accessible,");
-               puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
-       }
-#endif
-
-       spi_release_bus(spi);
-
-       return flash;
-
-err_manufacturer_probe:
-err_read_id:
-       spi_release_bus(spi);
-err_claim_bus:
-       spi_free_slave(spi);
-       return NULL;
-}
-
-void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi,
-                        const char *name)
-{
-       struct spi_flash *flash;
-       void *ptr;
-
-       ptr = malloc(size);
-       if (!ptr) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-       memset(ptr, '\0', size);
-       flash = (struct spi_flash *)(ptr + offset);
-
-       /* Set up some basic fields - caller will sort out sizes */
-       flash->spi = spi;
-       flash->name = name;
-       flash->poll_cmd = CMD_READ_STATUS;
-
-       flash->read = spi_flash_cmd_read_fast;
-       flash->write = spi_flash_cmd_write_multi;
-       flash->erase = spi_flash_cmd_erase;
-
-       return flash;
-}
-
-void spi_flash_free(struct spi_flash *flash)
-{
-       spi_free_slave(flash->spi);
-       free(flash);
-}
diff --git a/drivers/mtd/spi/sst.c b/drivers/mtd/spi/sst.c
deleted file mode 100644 (file)
index 256867c..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Driver for SST serial flashes
- *
- * (C) Copyright 2000-2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * Copyright 2008, Network Appliance Inc.
- * Jason McMullan <mcmullan@netapp.com>
- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
- * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
- * Copyright (c) 2008-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-#define CMD_SST_BP             0x02    /* Byte Program */
-#define CMD_SST_AAI_WP         0xAD    /* Auto Address Incr Word Program */
-
-#define SST_SR_WIP             (1 << 0)        /* Write-in-Progress */
-#define SST_SR_WEL             (1 << 1)        /* Write enable */
-#define SST_SR_BP0             (1 << 2)        /* Block Protection 0 */
-#define SST_SR_BP1             (1 << 3)        /* Block Protection 1 */
-#define SST_SR_BP2             (1 << 4)        /* Block Protection 2 */
-#define SST_SR_AAI             (1 << 6)        /* Addressing mode */
-#define SST_SR_BPL             (1 << 7)        /* BP bits lock */
-
-#define SST_FEAT_WP            (1 << 0)        /* Supports AAI word program */
-#define SST_FEAT_MBP           (1 << 1)        /* Supports multibyte program */
-
-struct sst_spi_flash_params {
-       u8 idcode1;
-       u8 flags;
-       u16 nr_sectors;
-       const char *name;
-};
-
-struct sst_spi_flash {
-       struct spi_flash flash;
-       const struct sst_spi_flash_params *params;
-};
-
-static const struct sst_spi_flash_params sst_spi_flash_table[] = {
-       {
-               .idcode1 = 0x8d,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 128,
-               .name = "SST25VF040B",
-       },
-       {
-               .idcode1 = 0x8e,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 256,
-               .name = "SST25VF080B",
-       },
-       {
-               .idcode1 = 0x41,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 512,
-               .name = "SST25VF016B",
-       },
-       {
-               .idcode1 = 0x4a,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 1024,
-               .name = "SST25VF032B",
-       },
-       {
-               .idcode1 = 0x4b,
-               .flags = SST_FEAT_MBP,
-               .nr_sectors = 2048,
-               .name = "SST25VF064C",
-       },
-       {
-               .idcode1 = 0x01,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 16,
-               .name = "SST25WF512",
-       },
-       {
-               .idcode1 = 0x02,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 32,
-               .name = "SST25WF010",
-       },
-       {
-               .idcode1 = 0x03,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 64,
-               .name = "SST25WF020",
-       },
-       {
-               .idcode1 = 0x04,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 128,
-               .name = "SST25WF040",
-       },
-       {
-               .idcode1 = 0x05,
-               .flags = SST_FEAT_WP,
-               .nr_sectors = 256,
-               .name = "SST25WF080",
-       },
-};
-
-static int
-sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
-{
-       int ret;
-       u8 cmd[4] = {
-               CMD_SST_BP,
-               offset >> 16,
-               offset >> 8,
-               offset,
-       };
-
-       debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
-             spi_w8r8(flash->spi, CMD_READ_STATUS), buf, cmd[0], offset);
-
-       ret = spi_flash_cmd_write_enable(flash);
-       if (ret)
-               return ret;
-
-       ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1);
-       if (ret)
-               return ret;
-
-       return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
-}
-
-static int
-sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, const void *buf)
-{
-       size_t actual, cmd_len;
-       int ret;
-       u8 cmd[4];
-
-       ret = spi_claim_bus(flash->spi);
-       if (ret) {
-               debug("SF: Unable to claim SPI bus\n");
-               return ret;
-       }
-
-       /* If the data is not word aligned, write out leading single byte */
-       actual = offset % 2;
-       if (actual) {
-               ret = sst_byte_write(flash, offset, buf);
-               if (ret)
-                       goto done;
-       }
-       offset += actual;
-
-       ret = spi_flash_cmd_write_enable(flash);
-       if (ret)
-               goto done;
-
-       cmd_len = 4;
-       cmd[0] = CMD_SST_AAI_WP;
-       cmd[1] = offset >> 16;
-       cmd[2] = offset >> 8;
-       cmd[3] = offset;
-
-       for (; actual < len - 1; actual += 2) {
-               debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
-                     spi_w8r8(flash->spi, CMD_READ_STATUS), buf + actual,
-                     cmd[0], offset);
-
-               ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len,
-                                       buf + actual, 2);
-               if (ret) {
-                       debug("SF: sst word program failed\n");
-                       break;
-               }
-
-               ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
-               if (ret)
-                       break;
-
-               cmd_len = 1;
-               offset += 2;
-       }
-
-       if (!ret)
-               ret = spi_flash_cmd_write_disable(flash);
-
-       /* If there is a single trailing byte, write it out */
-       if (!ret && actual != len)
-               ret = sst_byte_write(flash, offset, buf + actual);
-
- done:
-       debug("SF: sst: program %s %zu bytes @ 0x%zx\n",
-             ret ? "failure" : "success", len, offset - actual);
-
-       spi_release_bus(flash->spi);
-       return ret;
-}
-
-struct spi_flash *
-spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
-{
-       const struct sst_spi_flash_params *params;
-       struct sst_spi_flash *stm;
-       size_t i;
-
-       for (i = 0; i < ARRAY_SIZE(sst_spi_flash_table); ++i) {
-               params = &sst_spi_flash_table[i];
-               if (params->idcode1 == idcode[2])
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(sst_spi_flash_table)) {
-               debug("SF: Unsupported SST ID %02x\n", idcode[1]);
-               return NULL;
-       }
-
-       stm = spi_flash_alloc(struct sst_spi_flash, spi, params->name);
-       if (!stm) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-
-       stm->params = params;
-
-       if (stm->params->flags & SST_FEAT_WP)
-               stm->flash.write = sst_write_wp;
-       stm->flash.page_size = 256;
-       stm->flash.sector_size = 4096;
-       stm->flash.size = stm->flash.sector_size * params->nr_sectors;
-
-       /* Flash powers up read-only, so clear BP# bits */
-       spi_flash_cmd_write_status(&stm->flash, 0);
-
-       return &stm->flash;
-}
diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c
deleted file mode 100644 (file)
index c5fa64e..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * (C) Copyright 2000-2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * Copyright 2008, Network Appliance Inc.
- * Jason McMullan <mcmullan@netapp.com>
- *
- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
- * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-/* M25Pxx-specific commands */
-#define CMD_M25PXX_RES 0xab    /* Release from DP, and Read Signature */
-
-struct stmicro_spi_flash_params {
-       u16 id;
-       u16 pages_per_sector;
-       u16 nr_sectors;
-       const char *name;
-};
-
-static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = {
-       {
-               .id = 0x2011,
-               .pages_per_sector = 128,
-               .nr_sectors = 4,
-               .name = "M25P10",
-       },
-       {
-               .id = 0x2015,
-               .pages_per_sector = 256,
-               .nr_sectors = 32,
-               .name = "M25P16",
-       },
-       {
-               .id = 0x2012,
-               .pages_per_sector = 256,
-               .nr_sectors = 4,
-               .name = "M25P20",
-       },
-       {
-               .id = 0x2016,
-               .pages_per_sector = 256,
-               .nr_sectors = 64,
-               .name = "M25P32",
-       },
-       {
-               .id = 0x2013,
-               .pages_per_sector = 256,
-               .nr_sectors = 8,
-               .name = "M25P40",
-       },
-       {
-               .id = 0x2017,
-               .pages_per_sector = 256,
-               .nr_sectors = 128,
-               .name = "M25P64",
-       },
-       {
-               .id = 0x2014,
-               .pages_per_sector = 256,
-               .nr_sectors = 16,
-               .name = "M25P80",
-       },
-       {
-               .id = 0x2018,
-               .pages_per_sector = 1024,
-               .nr_sectors = 64,
-               .name = "M25P128",
-       },
-       {
-               .id = 0xba16,
-               .pages_per_sector = 256,
-               .nr_sectors = 64,
-               .name = "N25Q32",
-       },
-       {
-               .id = 0xbb16,
-               .pages_per_sector = 256,
-               .nr_sectors = 64,
-               .name = "N25Q32A",
-       },
-       {
-               .id = 0xba17,
-               .pages_per_sector = 256,
-               .nr_sectors = 128,
-               .name = "N25Q064",
-       },
-       {
-               .id = 0xbb17,
-               .pages_per_sector = 256,
-               .nr_sectors = 128,
-               .name = "N25Q64A",
-       },
-       {
-               .id = 0xba18,
-               .pages_per_sector = 256,
-               .nr_sectors = 256,
-               .name = "N25Q128",
-       },
-       {
-               .id = 0xbb18,
-               .pages_per_sector = 256,
-               .nr_sectors = 256,
-               .name = "N25Q128A",
-       },
-       {
-               .id = 0xba19,
-               .pages_per_sector = 256,
-               .nr_sectors = 512,
-               .name = "N25Q256",
-       },
-       {
-               .id = 0xbb19,
-               .pages_per_sector = 256,
-               .nr_sectors = 512,
-               .name = "N25Q256A",
-       },
-       {
-               .id = 0xba20,
-               .pages_per_sector = 256,
-               .nr_sectors = 1024,
-               .name = "N25Q512",
-       },
-       {
-               .id = 0xbb20,
-               .pages_per_sector = 256,
-               .nr_sectors = 1024,
-               .name = "N25Q512A",
-       },
-       {
-               .id = 0xba21,
-               .pages_per_sector = 256,
-               .nr_sectors = 2048,
-               .name = "N25Q1024",
-       },
-       {
-               .id = 0xbb21,
-               .pages_per_sector = 256,
-               .nr_sectors = 2048,
-               .name = "N25Q1024A",
-       },
-};
-
-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode)
-{
-       const struct stmicro_spi_flash_params *params;
-       struct spi_flash *flash;
-       unsigned int i;
-       u16 id;
-
-       if (idcode[0] == 0xff) {
-               i = spi_flash_cmd(spi, CMD_M25PXX_RES,
-                                 idcode, 4);
-               if (i)
-                       return NULL;
-               if ((idcode[3] & 0xf0) == 0x10) {
-                       idcode[0] = 0x20;
-                       idcode[1] = 0x20;
-                       idcode[2] = idcode[3] + 1;
-               } else {
-                       return NULL;
-               }
-       }
-
-       id = ((idcode[1] << 8) | idcode[2]);
-
-       for (i = 0; i < ARRAY_SIZE(stmicro_spi_flash_table); i++) {
-               params = &stmicro_spi_flash_table[i];
-               if (params->id == id)
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(stmicro_spi_flash_table)) {
-               debug("SF: Unsupported STMicro ID %04x\n", id);
-               return NULL;
-       }
-
-       flash = spi_flash_alloc_base(spi, params->name);
-       if (!flash) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-
-       flash->page_size = 256;
-       flash->sector_size = 256 * params->pages_per_sector;
-       flash->size = flash->sector_size * params->nr_sectors;
-
-       /* for >= 512MiB flashes, use flag status instead of read_status */
-       if (flash->size >= 0x4000000)
-               flash->poll_cmd = CMD_FLAG_STATUS;
-
-       return flash;
-}
diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c
deleted file mode 100644 (file)
index b31911a..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2008, Network Appliance Inc.
- * Author: Jason McMullan <mcmullan <at> netapp.com>
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <spi_flash.h>
-
-#include "spi_flash_internal.h"
-
-struct winbond_spi_flash_params {
-       uint16_t        id;
-       uint16_t        nr_blocks;
-       const char      *name;
-};
-
-static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
-       {
-               .id                     = 0x2014,
-               .nr_blocks              = 16,
-               .name                   = "W25P80",
-       },
-       {
-               .id                     = 0x2015,
-               .nr_blocks              = 32,
-               .name                   = "W25P16",
-       },
-       {
-               .id                     = 0x2016,
-               .nr_blocks              = 64,
-               .name                   = "W25P32",
-       },
-       {
-               .id                     = 0x3013,
-               .nr_blocks              = 8,
-               .name                   = "W25X40",
-       },
-       {
-               .id                     = 0x3015,
-               .nr_blocks              = 32,
-               .name                   = "W25X16",
-       },
-       {
-               .id                     = 0x3016,
-               .nr_blocks              = 64,
-               .name                   = "W25X32",
-       },
-       {
-               .id                     = 0x3017,
-               .nr_blocks              = 128,
-               .name                   = "W25X64",
-       },
-       {
-               .id                     = 0x4014,
-               .nr_blocks              = 16,
-               .name                   = "W25Q80BL/W25Q80BV",
-       },
-       {
-               .id                     = 0x4015,
-               .nr_blocks              = 32,
-               .name                   = "W25Q16CL/W25Q16DV",
-       },
-       {
-               .id                     = 0x4016,
-               .nr_blocks              = 64,
-               .name                   = "W25Q32BV/W25Q32FV_SPI",
-       },
-       {
-               .id                     = 0x4017,
-               .nr_blocks              = 128,
-               .name                   = "W25Q64CV/W25Q64FV_SPI",
-       },
-       {
-               .id                     = 0x4018,
-               .nr_blocks              = 256,
-               .name                   = "W25Q128BV/W25Q128FV_SPI",
-       },
-       {
-               .id                     = 0x4019,
-               .nr_blocks              = 512,
-               .name                   = "W25Q256",
-       },
-       {
-               .id                     = 0x5014,
-               .nr_blocks              = 16,
-               .name                   = "W25Q80BW",
-       },
-       {
-               .id                     = 0x6015,
-               .nr_blocks              = 32,
-               .name                   = "W25Q16DW",
-       },
-       {
-               .id                     = 0x6016,
-               .nr_blocks              = 64,
-               .name                   = "W25Q32DW/W25Q32FV_QPI",
-       },
-       {
-               .id                     = 0x6017,
-               .nr_blocks              = 128,
-               .name                   = "W25Q64DW/W25Q64FV_QPI",
-       },
-       {
-               .id                     = 0x6018,
-               .nr_blocks              = 256,
-               .name                   = "W25Q128FW/W25Q128FV_QPI",
-       },
-};
-
-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
-{
-       const struct winbond_spi_flash_params *params;
-       struct spi_flash *flash;
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
-               params = &winbond_spi_flash_table[i];
-               if (params->id == ((idcode[1] << 8) | idcode[2]))
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
-               debug("SF: Unsupported Winbond ID %02x%02x\n",
-                     idcode[1], idcode[2]);
-               return NULL;
-       }
-
-       flash = spi_flash_alloc_base(spi, params->name);
-       if (!flash) {
-               debug("SF: Failed to allocate memory\n");
-               return NULL;
-       }
-
-       flash->page_size = 256;
-       flash->sector_size = (idcode[1] == 0x20) ? 65536 : 4096;
-       flash->size = 4096 * 16 * params->nr_blocks;
-
-       return flash;
-}
index c98867dc4aa39b9fc0144973f4c2096151ee7146..381ec42864fb618c867ad2524b6f5ba452417967 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*-----------------------------------------------------------------------------+
  *
index 07fcb60e9d1e8a5f8412983e0cf6e85090e968c9..002fb8113b25ffab35a4fa3724765288ea7f9636 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  */
 /*-----------------------------------------------------------------------------+
   |
index 5936f9bd7f31f18b2a53a369b2130eb7a86caa15..60ed92d2039ba36846a7ef83ceb870b01bec8795 100644 (file)
@@ -7,7 +7,7 @@
  *   Copyright 2010-2011 Freescale Semiconductor, Inc.
  *   author Andy Fleming
  *
- * Some code get from linux kenrel
+ * Some code copied from linux kernel
  * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
  */
 #include <miiphy.h>
index c4ed8ba6c3157fe9646c98a1a5896a39f2137e6e..86ba6b523c11da2f7eb5ed47fe31b7798d1f59d1 100644 (file)
@@ -297,7 +297,7 @@ void pciauto_config_init(struct pci_controller *hose)
 {
        int i;
 
-       hose->pci_io = hose->pci_mem = NULL;
+       hose->pci_io = hose->pci_mem = hose->pci_prefetch = NULL;
 
        for (i = 0; i < hose->region_count; i++) {
                switch(hose->regions[i].flags) {
index d79971ba884154a469d602d806420e866509b08e..29ccc831af2d80c3bcc4cadb5f80b95170088015 100644 (file)
@@ -184,18 +184,21 @@ int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                if (argc < 4)
                        return CMD_RET_USAGE;
 
+               if (!p->pbat) {
+                       printf("%s is not a battery\n", p->name);
+                       return CMD_RET_FAILURE;
+               }
+
                if (strcmp(argv[3], "state") == 0)
                        p->fg->fg_battery_check(p->pbat->fg, p);
 
                if (strcmp(argv[3], "charge") == 0) {
-                       if (p->pbat) {
-                               printf("BAT: %s charging (ctrl+c to break)\n",
-                                      p->name);
-                               if (p->low_power_mode)
-                                       p->low_power_mode();
-                               if (p->pbat->battery_charge)
-                                       p->pbat->battery_charge(p);
-                       }
+                       printf("BAT: %s charging (ctrl+c to break)\n",
+                              p->name);
+                       if (p->low_power_mode)
+                               p->low_power_mode();
+                       if (p->pbat->battery_charge)
+                               p->pbat->battery_charge(p);
                }
 
                return CMD_RET_SUCCESS;
index d69db58dcd2e8a3c366303646cf4b79d796408b8..febf4195ba9b8870183d409f3ca4743e18118bc0 100644 (file)
@@ -52,7 +52,7 @@ int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
 static int max98095_i2c_write(unsigned int reg, unsigned char data)
 {
        debug("%s: Write Addr : 0x%02X, Data :  0x%02X\n",
-               __func__, reg, data);
+             __func__, reg, data);
        return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1);
 }
 
@@ -71,7 +71,7 @@ static unsigned int max98095_i2c_read(unsigned int reg, unsigned char *data)
        ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1);
        if (ret != 0) {
                debug("%s: Error while reading register %#04x\n",
-                       __func__, reg);
+                     __func__, reg);
                return -1;
        }
 
@@ -138,43 +138,57 @@ static int rate_value(int rate, u8 *value)
  * @return -1 for error  and 0  Success.
  */
 static int max98095_hw_params(struct max98095_priv *max98095,
-               unsigned int rate, unsigned int bits_per_sample)
+                             enum en_max_audio_interface aif_id,
+                             unsigned int rate, unsigned int bits_per_sample)
 {
        u8 regval;
        int error;
+       unsigned short M98095_DAI_CLKMODE;
+       unsigned short M98095_DAI_FORMAT;
+       unsigned short M98095_DAI_FILTERS;
+
+       if (aif_id == AIF1) {
+               M98095_DAI_CLKMODE = M98095_027_DAI1_CLKMODE;
+               M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
+               M98095_DAI_FILTERS = M98095_02E_DAI1_FILTERS;
+       } else {
+               M98095_DAI_CLKMODE = M98095_031_DAI2_CLKMODE;
+               M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
+               M98095_DAI_FILTERS = M98095_038_DAI2_FILTERS;
+       }
 
        switch (bits_per_sample) {
        case 16:
-               error = max98095_update_bits(M98095_034_DAI2_FORMAT,
-                       M98095_DAI_WS, 0);
+               error = max98095_update_bits(M98095_DAI_FORMAT,
+                                            M98095_DAI_WS, 0);
                break;
        case 24:
-               error = max98095_update_bits(M98095_034_DAI2_FORMAT,
-                       M98095_DAI_WS, M98095_DAI_WS);
+               error = max98095_update_bits(M98095_DAI_FORMAT,
+                                            M98095_DAI_WS, M98095_DAI_WS);
                break;
        default:
                debug("%s: Illegal bits per sample %d.\n",
-                       __func__, bits_per_sample);
+                     __func__, bits_per_sample);
                return -1;
        }
 
        if (rate_value(rate, &regval)) {
                debug("%s: Failed to set sample rate to %d.\n",
-                       __func__, rate);
+                     __func__, rate);
                return -1;
        }
        max98095->rate = rate;
 
-       error |= max98095_update_bits(M98095_031_DAI2_CLKMODE,
-               M98095_CLKMODE_MASK, regval);
+       error |= max98095_update_bits(M98095_DAI_CLKMODE,
+                                     M98095_CLKMODE_MASK, regval);
 
        /* Update sample rate mode */
        if (rate < 50000)
-               error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
-                       M98095_DAI_DHF, 0);
+               error |= max98095_update_bits(M98095_DAI_FILTERS,
+                                             M98095_DAI_DHF, 0);
        else
-               error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
-                       M98095_DAI_DHF, M98095_DAI_DHF);
+               error |= max98095_update_bits(M98095_DAI_FILTERS,
+                                             M98095_DAI_DHF, M98095_DAI_DHF);
 
        if (error < 0) {
                debug("%s: Error setting hardware params.\n", __func__);
@@ -193,7 +207,7 @@ static int max98095_hw_params(struct max98095_priv *max98095,
  * @return -1 for error and 0 success.
  */
 static int max98095_set_sysclk(struct max98095_priv *max98095,
-                               unsigned int freq)
+                              unsigned int freq)
 {
        int error = 0;
 
@@ -235,22 +249,39 @@ static int max98095_set_sysclk(struct max98095_priv *max98095,
  *
  * @return -1 for error and 0  Success.
  */
-static int max98095_set_fmt(struct max98095_priv *max98095, int fmt)
+static int max98095_set_fmt(struct max98095_priv *max98095, int fmt,
+                           enum en_max_audio_interface aif_id)
 {
        u8 regval = 0;
        int error = 0;
+       unsigned short M98095_DAI_CLKCFG_HI;
+       unsigned short M98095_DAI_CLKCFG_LO;
+       unsigned short M98095_DAI_FORMAT;
+       unsigned short M98095_DAI_CLOCK;
 
        if (fmt == max98095->fmt)
                return 0;
 
        max98095->fmt = fmt;
 
+       if (aif_id == AIF1) {
+               M98095_DAI_CLKCFG_HI = M98095_028_DAI1_CLKCFG_HI;
+               M98095_DAI_CLKCFG_LO = M98095_029_DAI1_CLKCFG_LO;
+               M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
+               M98095_DAI_CLOCK = M98095_02B_DAI1_CLOCK;
+       } else {
+               M98095_DAI_CLKCFG_HI = M98095_032_DAI2_CLKCFG_HI;
+               M98095_DAI_CLKCFG_LO = M98095_033_DAI2_CLKCFG_LO;
+               M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
+               M98095_DAI_CLOCK = M98095_035_DAI2_CLOCK;
+       }
+
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
                /* Slave mode PLL */
-               error |= max98095_i2c_write(M98095_032_DAI2_CLKCFG_HI,
+               error |= max98095_i2c_write(M98095_DAI_CLKCFG_HI,
                                        0x80);
-               error |= max98095_i2c_write(M98095_033_DAI2_CLKCFG_LO,
+               error |= max98095_i2c_write(M98095_DAI_CLKCFG_LO,
                                        0x00);
                break;
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -292,12 +323,13 @@ static int max98095_set_fmt(struct max98095_priv *max98095, int fmt)
                return -1;
        }
 
-       error |= max98095_update_bits(M98095_034_DAI2_FORMAT,
-               M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
-               M98095_DAI_WCI, regval);
+       error |= max98095_update_bits(M98095_DAI_FORMAT,
+                                     M98095_DAI_MAS | M98095_DAI_DLY |
+                                     M98095_DAI_BCI | M98095_DAI_WCI,
+                                     regval);
 
-       error |= max98095_i2c_write(M98095_035_DAI2_CLOCK,
-               M98095_DAI_BSEL64);
+       error |= max98095_i2c_write(M98095_DAI_CLOCK,
+                                   M98095_DAI_BSEL64);
 
        if (error < 0) {
                debug("%s: Error setting i2s format.\n", __func__);
@@ -354,7 +386,8 @@ static int max98095_reset(void)
  *
  * @returns -1 for error  and 0 Success.
  */
-static int max98095_device_init(struct max98095_priv *max98095)
+static int max98095_device_init(struct max98095_priv *max98095,
+                               enum en_max_audio_interface aif_id)
 {
        unsigned char id;
        int error = 0;
@@ -374,7 +407,7 @@ static int max98095_device_init(struct max98095_priv *max98095)
        error = max98095_i2c_read(M98095_0FF_REV_ID, &id);
        if (error < 0) {
                debug("%s: Failure reading hardware revision: %d\n",
-                       __func__, id);
+                     __func__, id);
                goto err_access;
        }
        debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A');
@@ -385,26 +418,28 @@ static int max98095_device_init(struct max98095_priv *max98095)
         * initialize registers to hardware default configuring audio
         * interface2 to DAC
         */
-       error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
-               M98095_DAI2M_TO_DACL|M98095_DAI2M_TO_DACR);
+       if (aif_id == AIF1)
+               error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
+                                           M98095_DAI1L_TO_DACL |
+                                           M98095_DAI1R_TO_DACR);
+       else
+               error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
+                                           M98095_DAI2M_TO_DACL |
+                                           M98095_DAI2M_TO_DACR);
 
        error |= max98095_i2c_write(M98095_092_PWR_EN_OUT,
-                       M98095_SPK_SPREADSPECTRUM);
-       error |= max98095_i2c_write(M98095_045_CFG_DSP, M98095_DSPNORMAL);
+                                   M98095_SPK_SPREADSPECTRUM);
        error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL);
-
-       error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
-                       M98095_S1NORMAL|M98095_SDATA);
-
-       error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
-                       M98095_S2NORMAL|M98095_SDATA);
-
-       error |= max98095_i2c_write(M98095_040_DAI3_IOCFG,
-                       M98095_S3NORMAL|M98095_SDATA);
+       if (aif_id == AIF1)
+               error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
+                                           M98095_S1NORMAL | M98095_SDATA);
+       else
+               error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
+                                           M98095_S2NORMAL | M98095_SDATA);
 
        /* take the codec out of the shut down */
        error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN,
-                       M98095_SHDNRUN);
+                                     M98095_SHDNRUN);
        /* route DACL and DACR output to HO and Spekers */
        error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */
        error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */
@@ -422,7 +457,10 @@ static int max98095_device_init(struct max98095_priv *max98095)
 
        /* Enable DAIs */
        error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30);
-       error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
+       if (aif_id == AIF1)
+               error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x01);
+       else
+               error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
 
 err_access:
        if (error < 0)
@@ -432,8 +470,9 @@ err_access:
 }
 
 static int max98095_do_init(struct sound_codec_info *pcodec_info,
-                       int sampling_rate, int mclk_freq,
-                       int bits_per_sample)
+                           enum en_max_audio_interface aif_id,
+                           int sampling_rate, int mclk_freq,
+                           int bits_per_sample)
 {
        int ret = 0;
 
@@ -443,15 +482,15 @@ static int max98095_do_init(struct sound_codec_info *pcodec_info,
        /* shift the device address by 1 for 7 bit addressing */
        g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1;
 
-       if (pcodec_info->codec_type == CODEC_MAX_98095)
+       if (pcodec_info->codec_type == CODEC_MAX_98095) {
                g_max98095_info.devtype = MAX98095;
-       else {
+       else {
                debug("%s: Codec id [%d] not defined\n", __func__,
-                               pcodec_info->codec_type);
+                     pcodec_info->codec_type);
                return -1;
        }
 
-       ret = max98095_device_init(&g_max98095_info);
+       ret = max98095_device_init(&g_max98095_info, aif_id);
        if (ret < 0) {
                debug("%s: max98095 codec chip init failed\n", __func__);
                return ret;
@@ -463,14 +502,15 @@ static int max98095_do_init(struct sound_codec_info *pcodec_info,
                return ret;
        }
 
-       ret = max98095_hw_params(&g_max98095_info, sampling_rate,
-                               bits_per_sample);
+       ret = max98095_hw_params(&g_max98095_info, aif_id, sampling_rate,
+                                bits_per_sample);
 
        if (ret == 0) {
                ret = max98095_set_fmt(&g_max98095_info,
-                                       SND_SOC_DAIFMT_I2S |
-                                       SND_SOC_DAIFMT_NB_NF |
-                                       SND_SOC_DAIFMT_CBS_CFS);
+                                      SND_SOC_DAIFMT_I2S |
+                                      SND_SOC_DAIFMT_NB_NF |
+                                      SND_SOC_DAIFMT_CBS_CFS,
+                                      aif_id);
        }
 
        return ret;
@@ -529,8 +569,9 @@ static int get_max98095_codec_values(struct sound_codec_info *pcodec_info,
 }
 
 /* max98095 Device Initialisation */
-int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
-                       int bits_per_sample)
+int max98095_init(const void *blob, enum en_max_audio_interface aif_id,
+                 int sampling_rate, int mclk_freq,
+                 int bits_per_sample)
 {
        int ret;
        int old_bus = i2c_get_bus_num();
@@ -538,12 +579,12 @@ int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
 
        if (get_max98095_codec_values(pcodec_info, blob) < 0) {
                debug("FDT Codec values failed\n");
-                return -1;
+               return -1;
        }
 
        i2c_set_bus_num(pcodec_info->i2c_bus);
-       ret = max98095_do_init(pcodec_info, sampling_rate, mclk_freq,
-                               bits_per_sample);
+       ret = max98095_do_init(pcodec_info, aif_id, sampling_rate, mclk_freq,
+                              bits_per_sample);
        i2c_set_bus_num(old_bus);
 
        return ret;
index ae5eb14dbb4f43447953cba4060cc4e0454a478c..44b1e3a97b4aa16280c8940368a6bd321e0a50df 100644 (file)
 #ifndef _MAX98095_H
 #define _MAX98095_H
 
+/*  Available audio interface ports in wm8994 codec */
+enum en_max_audio_interface {
+       AIF1 = 1,
+       AIF2,
+};
+
 /*
  * MAX98095 Registers Definition
  */
  *
  * @returns -1 for error and 0 Success.
  */
-int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
-                       int bits_per_sample);
+int max98095_init(const void *blob, enum en_max_audio_interface aif_id,
+                 int sampling_rate, int mclk_freq, int bits_per_sample);
 
 #endif
index 49921e55266faeaf70277f8d568fe7807c3938c0..47f155f85d525c15a57e71d0a1d34e60847dfa6a 100644 (file)
@@ -65,9 +65,7 @@ static void i2s_txctrl(struct i2s_reg *i2s_reg, int on)
        if (on) {
                con |= CON_ACTIVE;
                con &= ~CON_TXCH_PAUSE;
-
        } else {
-
                con |=  CON_TXCH_PAUSE;
                con &= ~CON_ACTIVE;
        }
@@ -172,7 +170,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
                break;
        default:
                debug("%s: Invalid format priority [0x%x]\n", __func__,
-                       (fmt & SND_SOC_DAIFMT_FORMAT_MASK));
+                     (fmt & SND_SOC_DAIFMT_FORMAT_MASK));
                return -1;
        }
 
@@ -191,7 +189,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
                break;
        default:
                debug("%s: Invalid clock ploarity input [0x%x]\n", __func__,
-                       (fmt & SND_SOC_DAIFMT_INV_MASK));
+                     (fmt & SND_SOC_DAIFMT_INV_MASK));
                return -1;
        }
 
@@ -209,7 +207,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
                break;
        default:
                debug("%s: Invalid master selection [0x%x]\n", __func__,
-                       (fmt & SND_SOC_DAIFMT_MASTER_MASK));
+                     (fmt & SND_SOC_DAIFMT_MASTER_MASK));
                return -1;
        }
 
@@ -250,7 +248,7 @@ int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc)
                break;
        default:
                debug("%s: Invalid sample size input [0x%x]\n",
-                       __func__, blc);
+                     __func__, blc);
                return -1;
        }
        writel(mod, &i2s_reg->mod);
@@ -301,27 +299,58 @@ int i2s_tx_init(struct i2stx_info *pi2s_tx)
        int ret;
        struct i2s_reg *i2s_reg =
                                (struct i2s_reg *)pi2s_tx->base_address;
+       if (pi2s_tx->id == 0) {
+               /* Initialize GPIO for I2S-0 */
+               exynos_pinmux_config(PERIPH_ID_I2S0, 0);
+
+               /* Set EPLL Clock */
+               ret = set_epll_clk(pi2s_tx->samplingrate * pi2s_tx->rfs * 4);
+       } else if (pi2s_tx->id == 1) {
+               /* Initialize GPIO for I2S-1 */
+               exynos_pinmux_config(PERIPH_ID_I2S1, 0);
+
+               /* Set EPLL Clock */
+               ret = set_epll_clk(pi2s_tx->audio_pll_clk);
+       } else {
+               debug("%s: unsupported i2s-%d bus\n", __func__, pi2s_tx->id);
+               return -1;
+       }
 
-       /* Initialize GPIO for I2s */
-       exynos_pinmux_config(PERIPH_ID_I2S1, 0);
-
-       /* Set EPLL Clock */
-       ret = set_epll_clk(pi2s_tx->audio_pll_clk);
        if (ret != 0) {
-               debug("%s: epll clock set rate falied\n", __func__);
+               debug("%s: epll clock set rate failed\n", __func__);
                return -1;
        }
 
-       /* Select Clk Source for Audio1 */
-       set_i2s_clk_source();
+       /* Select Clk Source for Audio 0 or 1 */
+       ret = set_i2s_clk_source(pi2s_tx->id);
+       if (ret == -1) {
+               debug("%s: unsupported clock for i2s-%d\n", __func__,
+                     pi2s_tx->id);
+               return -1;
+       }
+
+       if (pi2s_tx->id == 0) {
+               /*Reset the i2s module */
+               writel(CON_RESET, &i2s_reg->con);
 
-       /* Set Prescaler to get MCLK */
-       set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
-                               (pi2s_tx->samplingrate * (pi2s_tx->rfs)));
+               writel(MOD_OP_CLK | MOD_RCLKSRC, &i2s_reg->mod);
+               /* set i2s prescaler */
+               writel(PSREN | PSVAL, &i2s_reg->psr);
+       } else {
+               /* Set Prescaler to get MCLK */
+               ret = set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
+                               (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                               pi2s_tx->id);
+       }
+       if (ret == -1) {
+               debug("%s: unsupported prescalar for i2s-%d\n", __func__,
+                     pi2s_tx->id);
+               return -1;
+       }
 
        /* Configure I2s format */
        ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-                               SND_SOC_DAIFMT_CBM_CFM));
+                         SND_SOC_DAIFMT_CBM_CFM));
        if (ret == 0) {
                i2s_set_lr_framesize(i2s_reg, pi2s_tx->rfs);
                ret = i2s_set_samplesize(i2s_reg, pi2s_tx->bitspersample);
index 6fcc75da58fa774415b48e19c655e3b7f26e26bf..9b8ce5a9efb752c78466f2b461385e448a49e2f9 100644 (file)
@@ -36,8 +36,7 @@ static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob)
        int error = 0;
        int base;
 
-       node = fdtdec_next_compatible(blob, 0,
-                                       COMPAT_SAMSUNG_EXYNOS5_SOUND);
+       node = fdt_path_offset(blob, "i2s");
        if (node <= 0) {
                debug("EXYNOS_SOUND: No node for sound in device tree\n");
                return -1;
@@ -80,6 +79,11 @@ static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob)
                                node, "samsung,i2s-bit-clk-framesize", -1);
        error |= i2s->bfs;
        debug("bfs = %d\n", i2s->bfs);
+
+       i2s->id = fdtdec_get_int(blob, node, "samsung,i2s-id", -1);
+       error |= i2s->id;
+       debug("id = %d\n", i2s->id);
+
        if (error == -1) {
                debug("fail to get sound i2s node properties\n");
                return -1;
@@ -92,6 +96,7 @@ static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob)
        i2s->channels = I2S_CHANNELS;
        i2s->rfs = I2S_RFS;
        i2s->bfs = I2S_BFS;
+       i2s->id = 0;
 #endif
        return 0;
 }
@@ -111,7 +116,7 @@ static int codec_init(const void *blob, struct i2stx_info *pi2s_tx)
        int node;
 
        /* Get the node from FDT for sound */
-       node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SOUND);
+       node = fdt_path_offset(blob, "i2s");
        if (node <= 0) {
                debug("EXYNOS_SOUND: No node for sound in device tree\n");
                debug("node = %d\n", node);
@@ -130,14 +135,15 @@ static int codec_init(const void *blob, struct i2stx_info *pi2s_tx)
 #endif
        if (!strcmp(codectype, "wm8994")) {
                /* Check the codec type and initialise the same */
-               ret = wm8994_init(blob, WM8994_AIF2,
-                       pi2s_tx->samplingrate,
-                       (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
-                       pi2s_tx->bitspersample, pi2s_tx->channels);
+               ret = wm8994_init(blob, pi2s_tx->id + 1,
+                                 pi2s_tx->samplingrate,
+                                 (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                                 pi2s_tx->bitspersample, pi2s_tx->channels);
        } else if (!strcmp(codectype, "max98095")) {
-               ret = max98095_init(blob, pi2s_tx->samplingrate,
-                               (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
-                               pi2s_tx->bitspersample);
+               ret = max98095_init(blob, pi2s_tx->id + 1,
+                                   pi2s_tx->samplingrate,
+                                   (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                                   pi2s_tx->bitspersample);
        } else {
                debug("%s: Unknown codec type %s\n", __func__, codectype);
                return -1;
@@ -230,7 +236,7 @@ int sound_play(uint32_t msec, uint32_t frequency)
        }
 
        sound_prepare_buffer((unsigned short *)data,
-                               data_size / sizeof(unsigned short), frequency);
+                            data_size / sizeof(unsigned short), frequency);
 
        while (msec >= 1000) {
                ret = i2s_transfer_tx_data(&g_i2stx_pri, data,
index 37e354c5c84db350527b42459eeef70875e80351..f8e9a6eadd62c6f9e5cf14189eec4cfcd1ec8069 100644 (file)
@@ -432,12 +432,12 @@ static int configure_aif_clock(struct wm8994_priv *wm8994, int aif)
        int ret;
 
        /* AIF(1/0) register adress offset calculated */
-       if (aif)
+       if (aif-1)
                offset = 4;
        else
                offset = 0;
 
-       switch (wm8994->sysclk[aif]) {
+       switch (wm8994->sysclk[aif-1]) {
        case WM8994_SYSCLK_MCLK1:
                reg1 |= SEL_MCLK1;
                rate = wm8994->mclk[0];
@@ -460,7 +460,7 @@ static int configure_aif_clock(struct wm8994_priv *wm8994, int aif)
 
        default:
                debug("%s: Invalid input clock selection [%d]\n",
-                     __func__, wm8994->sysclk[aif]);
+                     __func__, wm8994->sysclk[aif-1]);
                return -1;
        }
 
@@ -470,13 +470,18 @@ static int configure_aif_clock(struct wm8994_priv *wm8994, int aif)
                reg1 |= WM8994_AIF1CLK_DIV;
        }
 
-       wm8994->aifclk[aif] = rate;
+       wm8994->aifclk[aif-1] = rate;
 
        ret = wm8994_update_bits(WM8994_AIF1_CLOCKING_1 + offset,
                                WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
                                reg1);
 
-       ret |= wm8994_update_bits(WM8994_CLOCKING_1,
+       if (aif == WM8994_AIF1)
+               ret |= wm8994_update_bits(WM8994_CLOCKING_1,
+                       WM8994_AIF1DSPCLK_ENA_MASK | WM8994_SYSDSPCLK_ENA_MASK,
+                       WM8994_AIF1DSPCLK_ENA | WM8994_SYSDSPCLK_ENA);
+       else if (aif == WM8994_AIF2)
+               ret |= wm8994_update_bits(WM8994_CLOCKING_1,
                        WM8994_SYSCLK_SRC | WM8994_AIF2DSPCLK_ENA_MASK |
                        WM8994_SYSDSPCLK_ENA_MASK, WM8994_SYSCLK_SRC |
                        WM8994_AIF2DSPCLK_ENA | WM8994_SYSDSPCLK_ENA);
@@ -536,7 +541,7 @@ static int wm8994_set_sysclk(struct wm8994_priv *wm8994, int aif_id,
                                        break;
                        if (i == ARRAY_SIZE(opclk_divs)) {
                                debug("%s frequency divisor not found\n",
-                                       __func__);
+                                     __func__);
                                return -1;
                        }
                        ret = wm8994_update_bits(WM8994_CLOCKING_2,
@@ -554,7 +559,7 @@ static int wm8994_set_sysclk(struct wm8994_priv *wm8994, int aif_id,
                return -1;
        }
 
-       ret |= configure_aif_clock(wm8994, aif_id - 1);
+       ret |= configure_aif_clock(wm8994, aif_id);
 
        if (ret < 0) {
                debug("%s: codec register access error\n", __func__);
@@ -607,6 +612,38 @@ static int wm8994_init_volume_aif2_dac1(void)
        return 0;
 }
 
+/*
+ * Initializes Volume for AIF1 to HP path
+ *
+ * @returns -1 for error  and 0 Success.
+ *
+ */
+static int wm8994_init_volume_aif1_dac1(void)
+{
+       int ret = 0;
+
+       /* Unmute AIF1DAC */
+       ret |= wm8994_i2c_write(WM8994_AIF1_DAC_FILTERS_1, 0x0000);
+
+       ret |= wm8994_update_bits(WM8994_DAC1_LEFT_VOLUME,
+                       WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK |
+                       WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
+
+       ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_VOLUME,
+                       WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK |
+                       WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
+       /* Head Phone Volume */
+       ret |= wm8994_i2c_write(WM8994_LEFT_OUTPUT_VOLUME, 0x12D);
+       ret |= wm8994_i2c_write(WM8994_RIGHT_OUTPUT_VOLUME, 0x12D);
+
+       if (ret < 0) {
+               debug("%s: codec register access error\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
 /*
  * Intialise wm8994 codec device
  *
@@ -614,7 +651,8 @@ static int wm8994_init_volume_aif2_dac1(void)
  *
  * @returns -1 for error  and 0 Success.
  */
-static int wm8994_device_init(struct wm8994_priv *wm8994)
+static int wm8994_device_init(struct wm8994_priv *wm8994,
+                             enum en_audio_interface aif_id)
 {
        const char *devname;
        unsigned short reg_data;
@@ -661,13 +699,30 @@ static int wm8994_device_init(struct wm8994_priv *wm8994)
        ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1,
                                WM8994_HPOUT1R_ENA_MASK, WM8994_HPOUT1R_ENA);
 
-       /* Power enable for AIF2 and DAC1 */
-       ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_5,
-               WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
-               WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK,
-               WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA | WM8994_DAC1L_ENA |
-               WM8994_DAC1R_ENA);
-
+       if (aif_id == WM8994_AIF1) {
+               ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_2,
+                                       WM8994_TSHUT_ENA | WM8994_MIXINL_ENA |
+                                       WM8994_MIXINR_ENA | WM8994_IN2L_ENA |
+                                       WM8994_IN2R_ENA);
+
+               ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_4,
+                                       WM8994_ADCL_ENA | WM8994_ADCR_ENA |
+                                       WM8994_AIF1ADC1R_ENA |
+                                       WM8994_AIF1ADC1L_ENA);
+
+               /* Power enable for AIF1 and DAC1 */
+               ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_5,
+                                       WM8994_AIF1DACL_ENA |
+                                       WM8994_AIF1DACR_ENA |
+                                       WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+       } else if (aif_id == WM8994_AIF2) {
+               /* Power enable for AIF2 and DAC1 */
+               ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_5,
+                       WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+                       WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK,
+                       WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+                       WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+       }
        /* Head Phone Initialisation */
        ret |= wm8994_update_bits(WM8994_ANALOGUE_HP_1,
                WM8994_HPOUT1L_DLY_MASK | WM8994_HPOUT1R_DLY_MASK,
@@ -695,35 +750,49 @@ static int wm8994_device_init(struct wm8994_priv *wm8994)
        ret |= wm8994_update_bits(WM8994_OUTPUT_MIXER_2,
                        WM8994_DAC1R_TO_HPOUT1R_MASK, WM8994_DAC1R_TO_HPOUT1R);
 
-       /* Routing AIF2 to DAC1 */
-       ret |= wm8994_update_bits(WM8994_DAC1_LEFT_MIXER_ROUTING,
-                       WM8994_AIF2DACL_TO_DAC1L_MASK,
-                       WM8994_AIF2DACL_TO_DAC1L);
-
-       ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING,
-                       WM8994_AIF2DACR_TO_DAC1R_MASK,
-                       WM8994_AIF2DACR_TO_DAC1R);
-
-        /* GPIO Settings for AIF2 */
-        /* B CLK */
-       ret |= wm8994_update_bits(WM8994_GPIO_3, WM8994_GPIO_DIR_MASK |
-                               WM8994_GPIO_FUNCTION_MASK ,
-                               WM8994_GPIO_DIR_OUTPUT |
-                               WM8994_GPIO_FUNCTION_I2S_CLK);
-
-       /* LR CLK */
-       ret |= wm8994_update_bits(WM8994_GPIO_4, WM8994_GPIO_DIR_MASK |
-                               WM8994_GPIO_FUNCTION_MASK,
-                               WM8994_GPIO_DIR_OUTPUT |
-                               WM8994_GPIO_FUNCTION_I2S_CLK);
-
-       /* DATA */
-       ret |= wm8994_update_bits(WM8994_GPIO_5, WM8994_GPIO_DIR_MASK |
-                               WM8994_GPIO_FUNCTION_MASK,
-                               WM8994_GPIO_DIR_OUTPUT |
-                               WM8994_GPIO_FUNCTION_I2S_CLK);
-
-       ret |= wm8994_init_volume_aif2_dac1();
+       if (aif_id == WM8994_AIF1) {
+               /* Routing AIF1 to DAC1 */
+               ret |= wm8994_i2c_write(WM8994_DAC1_LEFT_MIXER_ROUTING,
+                               WM8994_AIF1DAC1L_TO_DAC1L);
+
+               ret |= wm8994_i2c_write(WM8994_DAC1_RIGHT_MIXER_ROUTING,
+                                       WM8994_AIF1DAC1R_TO_DAC1R);
+
+               /* GPIO Settings for AIF1 */
+               ret |=  wm8994_i2c_write(WM8994_GPIO_1, WM8994_GPIO_DIR_OUTPUT
+                                        | WM8994_GPIO_FUNCTION_I2S_CLK
+                                        | WM8994_GPIO_INPUT_DEBOUNCE);
+
+               ret |= wm8994_init_volume_aif1_dac1();
+       } else if (aif_id == WM8994_AIF2) {
+               /* Routing AIF2 to DAC1 */
+               ret |= wm8994_update_bits(WM8994_DAC1_LEFT_MIXER_ROUTING,
+                               WM8994_AIF2DACL_TO_DAC1L_MASK,
+                               WM8994_AIF2DACL_TO_DAC1L);
+
+               ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING,
+                               WM8994_AIF2DACR_TO_DAC1R_MASK,
+                               WM8994_AIF2DACR_TO_DAC1R);
+
+               /* GPIO Settings for AIF2 */
+               /* B CLK */
+               ret |= wm8994_update_bits(WM8994_GPIO_3, WM8994_GPIO_DIR_MASK |
+                                       WM8994_GPIO_FUNCTION_MASK ,
+                                       WM8994_GPIO_DIR_OUTPUT);
+
+               /* LR CLK */
+               ret |= wm8994_update_bits(WM8994_GPIO_4, WM8994_GPIO_DIR_MASK |
+                                       WM8994_GPIO_FUNCTION_MASK,
+                                       WM8994_GPIO_DIR_OUTPUT);
+
+               /* DATA */
+               ret |= wm8994_update_bits(WM8994_GPIO_5, WM8994_GPIO_DIR_MASK |
+                                       WM8994_GPIO_FUNCTION_MASK,
+                                       WM8994_GPIO_DIR_OUTPUT);
+
+               ret |= wm8994_init_volume_aif2_dac1();
+       }
+
        if (ret < 0)
                goto err;
 
@@ -795,7 +864,7 @@ static int get_codec_values(struct sound_codec_info *pcodec_info,
        return 0;
 }
 
-/*wm8994 Device Initialisation */
+/* WM8994 Device Initialisation */
 int wm8994_init(const void *blob, enum en_audio_interface aif_id,
                        int sampling_rate, int mclk_freq,
                        int bits_per_sample, unsigned int channels)
@@ -813,15 +882,15 @@ int wm8994_init(const void *blob, enum en_audio_interface aif_id,
        g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr;
        wm8994_i2c_init(pcodec_info->i2c_bus);
 
-       if (pcodec_info->codec_type == CODEC_WM_8994)
+       if (pcodec_info->codec_type == CODEC_WM_8994) {
                g_wm8994_info.type = WM8994;
-       else {
+       else {
                debug("%s: Codec id [%d] not defined\n", __func__,
-                               pcodec_info->codec_type);
+                     pcodec_info->codec_type);
                return -1;
        }
 
-       ret = wm8994_device_init(&g_wm8994_info);
+       ret = wm8994_device_init(&g_wm8994_info, aif_id);
        if (ret < 0) {
                debug("%s: wm8994 codec chip init failed\n", __func__);
                return ret;
index 1e987c2fd1dc9374f2a6cc5384d2a237ac4ce010..0aba2fdfd88d155ce1e21816a6def5cb648f4492 100644 (file)
@@ -13,6 +13,7 @@
 #define WM8994_SOFTWARE_RESET                   0x00
 #define WM8994_POWER_MANAGEMENT_1               0x01
 #define WM8994_POWER_MANAGEMENT_2               0x02
+#define WM8994_POWER_MANAGEMENT_4              0x04
 #define WM8994_POWER_MANAGEMENT_5               0x05
 #define WM8994_LEFT_OUTPUT_VOLUME               0x1C
 #define WM8994_RIGHT_OUTPUT_VOLUME              0x1D
@@ -38,6 +39,7 @@
 #define WM8994_AIF2_CONTROL_2                   0x311
 #define WM8994_AIF2_MASTER_SLAVE                0x312
 #define WM8994_AIF2_BCLK                        0x313
+#define WM8994_AIF1_DAC_FILTERS_1              0x420
 #define WM8994_AIF2_DAC_LEFT_VOLUME             0x502
 #define WM8994_AIF2_DAC_RIGHT_VOLUME            0x503
 #define WM8994_AIF2_DAC_FILTERS_1               0x520
@@ -45,6 +47,7 @@
 #define WM8994_DAC1_RIGHT_MIXER_ROUTING         0x602
 #define WM8994_DAC1_LEFT_VOLUME                 0x610
 #define WM8994_DAC1_RIGHT_VOLUME                0x611
+#define WM8994_GPIO_1                          0x700
 #define WM8994_GPIO_3                           0x702
 #define WM8994_GPIO_4                           0x703
 #define WM8994_GPIO_5                           0x704
 /* OPCLK_ENA */
 #define WM8994_OPCLK_ENA                        0x0800
 
+#define WM8994_TSHUT_ENA                       0x4000
+#define WM8994_MIXINL_ENA                      0x0200
+#define WM8994_MIXINR_ENA                      0x0100
+#define WM8994_IN2L_ENA                                0x0080
+#define WM8994_IN2R_ENA                                0x0020
+
+/*
+ * R5 (0x04) - Power Management (4)
+ */
+#define WM8994_ADCL_ENA                                0x0001
+#define WM8994_ADCR_ENA                                0x0002
+#define WM8994_AIF1ADC1R_ENA                   0x0100
+#define WM8994_AIF1ADC1L_ENA                   0x0200
+
 /*
  * R5 (0x05) - Power Management (5)
  */
 /* AIF2DACR_ENA */
 #define WM8994_AIF2DACR_ENA                     0x1000
 #define WM8994_AIF2DACR_ENA_MASK                0x1000
+/* AIF1DACL_ENA */
+#define WM8994_AIF1DACL_ENA                    0x0200
+#define WM8994_AIF1DACL_ENA_MASK               0x0200
+/* AIF1DACR_ENA */
+#define WM8994_AIF1DACR_ENA                    0x0100
+#define WM8994_AIF1DACR_ENA_MASK               0x0100
 /* DAC1L_ENA */
 #define WM8994_DAC1L_ENA                        0x0002
 #define WM8994_DAC1L_ENA_MASK                   0x0002
 /*
  * R520 (0x208) - Clocking (1)
  */
+/* AIF1DSPCLK_ENA */
+#define WM8994_AIF1DSPCLK_ENA                  0x0008
+#define WM8994_AIF1DSPCLK_ENA_MASK             0x0008
 /* AIF2DSPCLK_ENA */
 #define WM8994_AIF2DSPCLK_ENA                   0x0004
 #define WM8994_AIF2DSPCLK_ENA_MASK              0x0004
 /* AIF2DACL_TO_DAC1L */
 #define WM8994_AIF2DACL_TO_DAC1L                0x0004
 #define WM8994_AIF2DACL_TO_DAC1L_MASK           0x0004
+/* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L              0x0001
 
 /*
  * R1538 (0x602) - DAC1 Right Mixer Routing
 /* AIF2DACR_TO_DAC1R */
 #define WM8994_AIF2DACR_TO_DAC1R                0x0004
 #define WM8994_AIF2DACR_TO_DAC1R_MASK           0x0004
+/* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R              0x0001
 
 /*
  * R1552 (0x610) - DAC1 Left Volume
  *  GPIO
  */
 /* OUTPUT PIN */
-#define WM8994_GPIO_DIR_OUTPUT                   0x8000
+#define WM8994_GPIO_DIR_OUTPUT                 0x8000
 /* GPIO PIN MASK */
-#define WM8994_GPIO_DIR_MASK                     0xFFE0
+#define WM8994_GPIO_DIR_MASK                   0xFFE0
 /* I2S CLK */
-#define WM8994_GPIO_FUNCTION_I2S_CLK             0x0000
+#define WM8994_GPIO_FUNCTION_I2S_CLK           0x0001
+#define WM8994_GPIO_INPUT_DEBOUNCE             0x0100
 /* GPn FN */
-#define WM8994_GPIO_FUNCTION_MASK                0x001F
+#define WM8994_GPIO_FUNCTION_MASK              0x001F
 #endif
index 91d24cea58da297d047121647ee39705583d513f..e5941b09f613438e843d82fb53dc1b6934557acf 100644 (file)
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_FDT_SPI) += fdt_spi.o
 COBJS-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
 COBJS-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
 COBJS-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
+COBJS-$(CONFIG_TI_QSPI) += ti_qspi.o
 COBJS-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 COBJS-$(CONFIG_ZYNQ_SPI) += zynq_spi.o
 
index efc8b1e3a59c59ac8467244d1514ab8e6caa2726..699c57eb6d99209a2180dd171224fa7be3f8d0fa 100644 (file)
@@ -26,6 +26,7 @@ struct spi_bus {
        struct exynos_spi *regs;
        int inited;             /* 1 if this bus is ready for use */
        int node;
+       uint deactivate_delay_us;       /* Delay to wait after deactivate */
 };
 
 /* A list of spi buses that we know about */
@@ -40,6 +41,8 @@ struct exynos_spi_slave {
        enum periph_id periph_id;       /* Peripheral ID for this device */
        unsigned int fifo_size;
        int skip_preamble;
+       struct spi_bus *bus;            /* Pointer to our SPI bus info */
+       ulong last_transaction_us;      /* Time of last transaction end */
 };
 
 static struct spi_bus *spi_get_bus(unsigned dev_index)
@@ -85,6 +88,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
        }
 
        bus = &spi_bus[busnum];
+       spi_slave->bus = bus;
        spi_slave->regs = bus->regs;
        spi_slave->mode = mode;
        spi_slave->periph_id = bus->periph_id;
@@ -95,6 +99,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
                spi_slave->fifo_size = 256;
 
        spi_slave->skip_preamble = 0;
+       spi_slave->last_transaction_us = timer_get_us();
 
        spi_slave->freq = bus->frequency;
        if (max_hz)
@@ -199,12 +204,29 @@ static void spi_get_fifo_levels(struct exynos_spi *regs,
  *
  * @param regs SPI peripheral registers
  * @param count        Number of bytes to transfer
+ * @param step Number of bytes to transfer in each packet (1 or 4)
  */
-static void spi_request_bytes(struct exynos_spi *regs, int count)
+static void spi_request_bytes(struct exynos_spi *regs, int count, int step)
 {
+       /* For word address we need to swap bytes */
+       if (step == 4) {
+               setbits_le32(&regs->mode_cfg,
+                            SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
+               count /= 4;
+               setbits_le32(&regs->swap_cfg, SPI_TX_SWAP_EN | SPI_RX_SWAP_EN |
+                       SPI_TX_BYTE_SWAP | SPI_RX_BYTE_SWAP |
+                       SPI_TX_HWORD_SWAP | SPI_RX_HWORD_SWAP);
+       } else {
+               /* Select byte access and clear the swap configuration */
+               clrbits_le32(&regs->mode_cfg,
+                            SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
+               writel(0, &regs->swap_cfg);
+       }
+
        assert(count && count < (1 << 16));
        setbits_le32(&regs->ch_cfg, SPI_CH_RST);
        clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
+
        writel(count | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
 }
 
@@ -219,17 +241,27 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
        int toread;
        unsigned start = get_timer(0);
        int stopping;
+       int step;
 
        out_bytes = in_bytes = todo;
 
        stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) &&
                                        !(spi_slave->mode & SPI_SLAVE);
 
+       /*
+        * Try to transfer words if we can. This helps read performance at
+        * SPI clock speeds above about 20MHz.
+        */
+       step = 1;
+       if (!((todo | (uintptr_t)rxp | (uintptr_t)txp) & 3) &&
+           !spi_slave->skip_preamble)
+               step = 4;
+
        /*
         * If there's something to send, do a software reset and set a
         * transaction size.
         */
-       spi_request_bytes(regs, todo);
+       spi_request_bytes(regs, todo, step);
 
        /*
         * Bytes are transmitted/received in pairs. Wait to receive all the
@@ -242,24 +274,42 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
 
                /* Keep the fifos full/empty. */
                spi_get_fifo_levels(regs, &rx_lvl, &tx_lvl);
-               if (tx_lvl < spi_slave->fifo_size && out_bytes) {
-                       temp = txp ? *txp++ : 0xff;
+
+               /*
+                * Don't completely fill the txfifo, since we don't want our
+                * rxfifo to overflow, and it may already contain data.
+                */
+               while (tx_lvl < spi_slave->fifo_size/2 && out_bytes) {
+                       if (!txp)
+                               temp = -1;
+                       else if (step == 4)
+                               temp = *(uint32_t *)txp;
+                       else
+                               temp = *txp;
                        writel(temp, &regs->tx_data);
-                       out_bytes--;
+                       out_bytes -= step;
+                       if (txp)
+                               txp += step;
+                       tx_lvl += step;
                }
-               if (rx_lvl > 0) {
-                       temp = readl(&regs->rx_data);
-                       if (spi_slave->skip_preamble) {
-                               if (temp == SPI_PREAMBLE_END_BYTE) {
-                                       spi_slave->skip_preamble = 0;
-                                       stopping = 0;
+               if (rx_lvl >= step) {
+                       while (rx_lvl >= step) {
+                               temp = readl(&regs->rx_data);
+                               if (spi_slave->skip_preamble) {
+                                       if (temp == SPI_PREAMBLE_END_BYTE) {
+                                               spi_slave->skip_preamble = 0;
+                                               stopping = 0;
+                                       }
+                               } else {
+                                       if (rxp || stopping) {
+                                               *rxp = temp;
+                                               rxp += step;
+                                       }
+                                       in_bytes -= step;
                                }
-                       } else {
-                               if (rxp || stopping)
-                                       *rxp++ = temp;
-                               in_bytes--;
+                               toread -= step;
+                               rx_lvl -= step;
                        }
-                       toread--;
                } else if (!toread) {
                        /*
                         * We have run out of input data, but haven't read
@@ -271,7 +321,7 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
                        out_bytes = in_bytes;
                        toread = in_bytes;
                        txp = NULL;
-                       spi_request_bytes(regs, toread);
+                       spi_request_bytes(regs, toread, step);
                }
                if (spi_slave->skip_preamble && get_timer(start) > 100) {
                        printf("SPI timeout: in_bytes=%d, out_bytes=%d, ",
@@ -315,10 +365,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
        if ((flags & SPI_XFER_BEGIN))
                spi_cs_activate(slave);
 
-       /* Exynos SPI limits each transfer to 65535 bytes */
+       /*
+        * Exynos SPI limits each transfer to 65535 transfers. To keep
+        * things simple, allow a maximum of 65532 bytes. We could allow
+        * more in word mode, but the performance difference is small.
+        */
        bytelen =  bitlen / 8;
        for (upto = 0; !ret && upto < bytelen; upto += todo) {
-               todo = min(bytelen - upto, (1 << 16) - 1);
+               todo = min(bytelen - upto, (1 << 16) - 4);
                ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags);
                if (ret)
                        break;
@@ -359,9 +413,22 @@ void spi_cs_activate(struct spi_slave *slave)
 {
        struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
 
+       /* If it's too soon to do another transaction, wait */
+       if (spi_slave->bus->deactivate_delay_us &&
+           spi_slave->last_transaction_us) {
+               ulong delay_us;         /* The delay completed so far */
+               delay_us = timer_get_us() - spi_slave->last_transaction_us;
+               if (delay_us < spi_slave->bus->deactivate_delay_us)
+                       udelay(spi_slave->bus->deactivate_delay_us - delay_us);
+       }
+
        clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
        debug("Activate CS, bus %d\n", spi_slave->slave.bus);
        spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
+
+       /* Remember time of this transaction so we can honour the bus delay */
+       if (spi_slave->bus->deactivate_delay_us)
+               spi_slave->last_transaction_us = timer_get_us();
 }
 
 /**
@@ -411,6 +478,8 @@ static int spi_get_config(const void *blob, int node, struct spi_bus *bus)
        /* Use 500KHz as a suitable default */
        bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
                                        500000);
+       bus->deactivate_delay_us = fdtdec_get_int(blob, node,
+                                       "spi-deactivate-delay", 0);
 
        return 0;
 }
index 3cf7142f5a62d0610fbf938fe74df672d5a5f99b..2b9f395a97821568dc12c5e28feaaf42b42ffd50 100644 (file)
@@ -56,8 +56,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                                  unsigned int max_hz, unsigned int mode)
 {
        struct mxs_spi_slave *mxs_slave;
-       struct mxs_ssp_regs *ssp_regs;
-       int reg;
 
        if (!spi_cs_is_valid(bus, cs)) {
                printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs);
@@ -74,13 +72,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        mxs_slave->max_khz = max_hz / 1000;
        mxs_slave->mode = mode;
        mxs_slave->regs = mxs_ssp_regs_by_bus(bus);
-       ssp_regs = mxs_slave->regs;
 
-       reg = readl(&ssp_regs->hw_ssp_ctrl0);
-       reg &= ~(MXS_SSP_CHIPSELECT_MASK);
-       reg |= cs << MXS_SSP_CHIPSELECT_SHIFT;
-
-       writel(reg, &ssp_regs->hw_ssp_ctrl0);
        return &mxs_slave->slave;
 
 err_init:
@@ -102,7 +94,9 @@ int spi_claim_bus(struct spi_slave *slave)
 
        mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg);
 
-       writel(SSP_CTRL0_BUS_WIDTH_ONE_BIT, &ssp_regs->hw_ssp_ctrl0);
+       writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) |
+              SSP_CTRL0_BUS_WIDTH_ONE_BIT,
+              &ssp_regs->hw_ssp_ctrl0);
 
        reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS;
        reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0;
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
new file mode 100644 (file)
index 0000000..5a5b482
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * TI QSPI driver
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/omap.h>
+#include <malloc.h>
+#include <spi.h>
+
+/* ti qpsi register bit masks */
+#define QSPI_TIMEOUT                    2000000
+#define QSPI_FCLK                       192000000
+/* clock control */
+#define QSPI_CLK_EN                     (1 << 31)
+#define QSPI_CLK_DIV_MAX                0xffff
+/* command */
+#define QSPI_EN_CS(n)                   (n << 28)
+#define QSPI_WLEN(n)                    ((n-1) << 19)
+#define QSPI_3_PIN                      (1 << 18)
+#define QSPI_RD_SNGL                    (1 << 16)
+#define QSPI_WR_SNGL                    (2 << 16)
+#define QSPI_INVAL                      (4 << 16)
+#define QSPI_RD_QUAD                    (7 << 16)
+/* device control */
+#define QSPI_DD(m, n)                   (m << (3 + n*8))
+#define QSPI_CKPHA(n)                   (1 << (2 + n*8))
+#define QSPI_CSPOL(n)                   (1 << (1 + n*8))
+#define QSPI_CKPOL(n)                   (1 << (n*8))
+/* status */
+#define QSPI_WC                         (1 << 1)
+#define QSPI_BUSY                       (1 << 0)
+#define QSPI_WC_BUSY                    (QSPI_WC | QSPI_BUSY)
+#define QSPI_XFER_DONE                  QSPI_WC
+#define MM_SWITCH                       0x01
+#define MEM_CS                          0x100
+#define MEM_CS_UNSELECT                 0xfffff0ff
+#define MMAP_START_ADDR                 0x5c000000
+#define CORE_CTRL_IO                    0x4a002558
+
+#define QSPI_CMD_READ                   (0x3 << 0)
+#define QSPI_CMD_READ_QUAD              (0x6b << 0)
+#define QSPI_CMD_READ_FAST              (0x0b << 0)
+#define QSPI_SETUP0_NUM_A_BYTES         (0x2 << 8)
+#define QSPI_SETUP0_NUM_D_BYTES_NO_BITS (0x0 << 10)
+#define QSPI_SETUP0_NUM_D_BYTES_8_BITS  (0x1 << 10)
+#define QSPI_SETUP0_READ_NORMAL         (0x0 << 12)
+#define QSPI_SETUP0_READ_QUAD           (0x3 << 12)
+#define QSPI_CMD_WRITE                  (0x2 << 16)
+#define QSPI_NUM_DUMMY_BITS             (0x0 << 24)
+
+/* ti qspi register set */
+struct ti_qspi_regs {
+       u32 pid;
+       u32 pad0[3];
+       u32 sysconfig;
+       u32 pad1[3];
+       u32 int_stat_raw;
+       u32 int_stat_en;
+       u32 int_en_set;
+       u32 int_en_ctlr;
+       u32 intc_eoi;
+       u32 pad2[3];
+       u32 clk_ctrl;
+       u32 dc;
+       u32 cmd;
+       u32 status;
+       u32 data;
+       u32 setup0;
+       u32 setup1;
+       u32 setup2;
+       u32 setup3;
+       u32 memswitch;
+       u32 data1;
+       u32 data2;
+       u32 data3;
+};
+
+/* ti qspi slave */
+struct ti_qspi_slave {
+       struct spi_slave slave;
+       struct ti_qspi_regs *base;
+       unsigned int mode;
+       u32 cmd;
+       u32 dc;
+};
+
+static inline struct ti_qspi_slave *to_ti_qspi_slave(struct spi_slave *slave)
+{
+       return container_of(slave, struct ti_qspi_slave, slave);
+}
+
+static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave)
+{
+       struct spi_slave *slave = &qslave->slave;
+       u32 memval = 0;
+
+       slave->memory_map = (void *)MMAP_START_ADDR;
+
+       memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES |
+                       QSPI_SETUP0_NUM_D_BYTES_NO_BITS |
+                       QSPI_SETUP0_READ_NORMAL | QSPI_CMD_WRITE |
+                       QSPI_NUM_DUMMY_BITS;
+
+       writel(memval, &qslave->base->setup0);
+}
+
+static void ti_spi_set_speed(struct spi_slave *slave, uint hz)
+{
+       struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave);
+       uint clk_div;
+
+       debug("ti_spi_set_speed: hz: %d, clock divider %d\n", hz, clk_div);
+
+       if (!hz)
+               clk_div = 0;
+       else
+               clk_div = (QSPI_FCLK / hz) - 1;
+
+       /* disable SCLK */
+       writel(readl(&qslave->base->clk_ctrl) & ~QSPI_CLK_EN,
+              &qslave->base->clk_ctrl);
+
+       /* assign clk_div values */
+       if (clk_div < 0)
+               clk_div = 0;
+       else if (clk_div > QSPI_CLK_DIV_MAX)
+               clk_div = QSPI_CLK_DIV_MAX;
+
+       /* enable SCLK */
+       writel(QSPI_CLK_EN | clk_div, &qslave->base->clk_ctrl);
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       return 1;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+       /* CS handled in xfer */
+       return;
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+       struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave);
+
+       debug("spi_cs_deactivate: 0x%08x\n", (u32)slave);
+
+       writel(qslave->cmd | QSPI_INVAL, &qslave->base->cmd);
+}
+
+void spi_init(void)
+{
+       /* nothing to do */
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode)
+{
+       struct ti_qspi_slave *qslave;
+
+       qslave = spi_alloc_slave(struct ti_qspi_slave, bus, cs);
+       if (!qslave) {
+               printf("SPI_error: Fail to allocate ti_qspi_slave\n");
+               return NULL;
+       }
+
+       qslave->base = (struct ti_qspi_regs *)QSPI_BASE;
+       qslave->mode = mode;
+
+       ti_spi_set_speed(&qslave->slave, max_hz);
+
+#ifdef CONFIG_TI_SPI_MMAP
+       ti_spi_setup_spi_register(qslave);
+#endif
+
+       return &qslave->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave);
+       free(qslave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave);
+
+       debug("spi_claim_bus: bus:%i cs:%i\n", slave->bus, slave->cs);
+
+       qslave->dc = 0;
+       if (qslave->mode & SPI_CPHA)
+               qslave->dc |= QSPI_CKPHA(slave->cs);
+       if (qslave->mode & SPI_CPOL)
+               qslave->dc |= QSPI_CKPOL(slave->cs);
+       if (qslave->mode & SPI_CS_HIGH)
+               qslave->dc |= QSPI_CSPOL(slave->cs);
+
+       writel(qslave->dc, &qslave->base->dc);
+       writel(0, &qslave->base->cmd);
+       writel(0, &qslave->base->data);
+
+       return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave);
+
+       debug("spi_release_bus: bus:%i cs:%i\n", slave->bus, slave->cs);
+
+       writel(0, &qslave->base->dc);
+       writel(0, &qslave->base->cmd);
+       writel(0, &qslave->base->data);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+            void *din, unsigned long flags)
+{
+       struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave);
+       uint words = bitlen >> 3; /* fixed 8-bit word length */
+       const uchar *txp = dout;
+       uchar *rxp = din;
+       uint status;
+       int timeout, val;
+
+       debug("spi_xfer: bus:%i cs:%i bitlen:%i words:%i flags:%lx\n",
+             slave->bus, slave->cs, bitlen, words, flags);
+
+       /* Setup mmap flags */
+       if (flags & SPI_XFER_MMAP) {
+               writel(MM_SWITCH, &qslave->base->memswitch);
+               val = readl(CORE_CTRL_IO);
+               val |= MEM_CS;
+               writel(val, CORE_CTRL_IO);
+               return 0;
+       } else if (flags & SPI_XFER_MMAP_END) {
+               writel(~MM_SWITCH, &qslave->base->memswitch);
+               val = readl(CORE_CTRL_IO);
+               val &= MEM_CS_UNSELECT;
+               writel(val, CORE_CTRL_IO);
+               return 0;
+       }
+
+       if (bitlen == 0)
+               return -1;
+
+       if (bitlen % 8) {
+               debug("spi_xfer: Non byte aligned SPI transfer\n");
+               return -1;
+       }
+
+       /* Setup command reg */
+       qslave->cmd = 0;
+       qslave->cmd |= QSPI_WLEN(8);
+       qslave->cmd |= QSPI_EN_CS(slave->cs);
+       if (flags & SPI_3WIRE)
+               qslave->cmd |= QSPI_3_PIN;
+       qslave->cmd |= 0xfff;
+
+       while (words--) {
+               if (txp) {
+                       debug("tx cmd %08x dc %08x data %02x\n",
+                             qslave->cmd | QSPI_WR_SNGL, qslave->dc, *txp);
+                       writel(*txp++, &qslave->base->data);
+                       writel(qslave->cmd | QSPI_WR_SNGL,
+                              &qslave->base->cmd);
+                       status = readl(&qslave->base->status);
+                       timeout = QSPI_TIMEOUT;
+                       while ((status & QSPI_WC_BUSY) != QSPI_XFER_DONE) {
+                               if (--timeout < 0) {
+                                       printf("spi_xfer: TX timeout!\n");
+                                       return -1;
+                               }
+                               status = readl(&qslave->base->status);
+                       }
+                       debug("tx done, status %08x\n", status);
+               }
+               if (rxp) {
+                       qslave->cmd |= QSPI_RD_SNGL;
+                       debug("rx cmd %08x dc %08x\n",
+                             qslave->cmd, qslave->dc);
+                       writel(qslave->cmd, &qslave->base->cmd);
+                       status = readl(&qslave->base->status);
+                       timeout = QSPI_TIMEOUT;
+                       while ((status & QSPI_WC_BUSY) != QSPI_XFER_DONE) {
+                               if (--timeout < 0) {
+                                       printf("spi_xfer: RX timeout!\n");
+                                       return -1;
+                               }
+                               status = readl(&qslave->base->status);
+                       }
+                       *rxp++ = readl(&qslave->base->data);
+                       debug("rx done, status %08x, read %02x\n",
+                             status, *(rxp-1));
+               }
+       }
+
+       /* Terminate frame */
+       if (flags & SPI_XFER_END)
+               spi_cs_deactivate(slave);
+
+       return 0;
+}
index 4c2a39a216a8d136d0c05a47df5f7d34b2dcac64..1590c4a7508f0976adac0dc5ece2f2a1ca616fb0 100644 (file)
@@ -18,10 +18,12 @@ endif
 
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
+COBJS-$(CONFIG_USB_GADGET_ATMEL_USBA) += atmel_usba_udc.o
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
 COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
+COBJS-$(CONFIG_USB_GADGET_MASS_STORAGE) += f_mass_storage.o
 endif
 ifdef CONFIG_USB_ETHER
 COBJS-y += ether.o
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
new file mode 100644 (file)
index 0000000..c99208d
--- /dev/null
@@ -0,0 +1,1306 @@
+/*
+ * Driver for the Atmel USBA high speed USB device controller
+ * [Original from Linux kernel: drivers/usb/gadget/atmel_usba_udc.c]
+ *
+ * Copyright (C) 2005-2013 Atmel Corporation
+ *                        Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+#include <asm/hardware.h>
+#include <linux/list.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/atmel_usba_udc.h>
+#include <malloc.h>
+#include <usb/lin_gadget_compat.h>
+
+#include "atmel_usba_udc.h"
+
+static int vbus_is_present(struct usba_udc *udc)
+{
+       /* No Vbus detection: Assume always present */
+       return 1;
+}
+
+static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req)
+{
+       unsigned int transaction_len;
+
+       transaction_len = req->req.length - req->req.actual;
+       req->last_transaction = 1;
+       if (transaction_len > ep->ep.maxpacket) {
+               transaction_len = ep->ep.maxpacket;
+               req->last_transaction = 0;
+       } else if (transaction_len == ep->ep.maxpacket && req->req.zero) {
+                       req->last_transaction = 0;
+       }
+
+       DBG(DBG_QUEUE, "%s: submit_transaction, req %p (length %d)%s\n",
+           ep->ep.name, req, transaction_len,
+           req->last_transaction ? ", done" : "");
+
+       memcpy(ep->fifo, req->req.buf + req->req.actual, transaction_len);
+       usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+       req->req.actual += transaction_len;
+}
+
+static void submit_request(struct usba_ep *ep, struct usba_request *req)
+{
+       DBG(DBG_QUEUE, "%s: submit_request: req %p (length %d), dma: %d\n",
+           ep->ep.name, req, req->req.length, req->using_dma);
+
+       req->req.actual = 0;
+       req->submitted = 1;
+
+       next_fifo_transaction(ep, req);
+       if (req->last_transaction) {
+               usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
+               usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
+       } else {
+               usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+               usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
+       }
+}
+
+static void submit_next_request(struct usba_ep *ep)
+{
+       struct usba_request *req;
+
+       if (list_empty(&ep->queue)) {
+               usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY | USBA_RX_BK_RDY);
+               return;
+       }
+
+       req = list_entry(ep->queue.next, struct usba_request, queue);
+       if (!req->submitted)
+               submit_request(ep, req);
+}
+
+static void send_status(struct usba_udc *udc, struct usba_ep *ep)
+{
+       ep->state = STATUS_STAGE_IN;
+       usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+       usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
+}
+
+static void receive_data(struct usba_ep *ep)
+{
+       struct usba_udc *udc = ep->udc;
+       struct usba_request *req;
+       unsigned long status;
+       unsigned int bytecount, nr_busy;
+       int is_complete = 0;
+
+       status = usba_ep_readl(ep, STA);
+       nr_busy = USBA_BFEXT(BUSY_BANKS, status);
+
+       DBG(DBG_QUEUE, "receive data: nr_busy=%u\n", nr_busy);
+
+       while (nr_busy > 0) {
+               if (list_empty(&ep->queue)) {
+                       usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+                       break;
+               }
+               req = list_entry(ep->queue.next,
+                                struct usba_request, queue);
+
+               bytecount = USBA_BFEXT(BYTE_COUNT, status);
+
+               if (status & USBA_SHORT_PACKET)
+                       is_complete = 1;
+               if (req->req.actual + bytecount >= req->req.length) {
+                       is_complete = 1;
+                       bytecount = req->req.length - req->req.actual;
+               }
+
+               memcpy(req->req.buf + req->req.actual, ep->fifo, bytecount);
+               req->req.actual += bytecount;
+
+               usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+
+               if (is_complete) {
+                       DBG(DBG_QUEUE, "%s: request done\n", ep->ep.name);
+                       req->req.status = 0;
+                       list_del_init(&req->queue);
+                       usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+                       spin_lock(&udc->lock);
+                       req->req.complete(&ep->ep, &req->req);
+                       spin_unlock(&udc->lock);
+               }
+
+               status = usba_ep_readl(ep, STA);
+               nr_busy = USBA_BFEXT(BUSY_BANKS, status);
+
+               if (is_complete && ep_is_control(ep)) {
+                       send_status(udc, ep);
+                       break;
+               }
+       }
+}
+
+static void
+request_complete(struct usba_ep *ep, struct usba_request *req, int status)
+{
+       if (req->req.status == -EINPROGRESS)
+               req->req.status = status;
+
+       DBG(DBG_GADGET | DBG_REQ, "%s: req %p complete: status %d, actual %u\n",
+           ep->ep.name, req, req->req.status, req->req.actual);
+
+       req->req.complete(&ep->ep, &req->req);
+}
+
+static void
+request_complete_list(struct usba_ep *ep, struct list_head *list, int status)
+{
+       struct usba_request *req, *tmp_req;
+
+       list_for_each_entry_safe(req, tmp_req, list, queue) {
+               list_del_init(&req->queue);
+               request_complete(ep, req, status);
+       }
+}
+
+static int
+usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
+{
+       struct usba_ep *ep = to_usba_ep(_ep);
+       struct usba_udc *udc = ep->udc;
+       unsigned long flags, ept_cfg, maxpacket;
+       unsigned int nr_trans;
+
+       DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc);
+
+       maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
+
+       if (((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
+             != ep->index) ||
+             ep->index == 0 ||
+             desc->bDescriptorType != USB_DT_ENDPOINT ||
+             maxpacket == 0 ||
+             maxpacket > ep->fifo_size) {
+               DBG(DBG_ERR, "ep_enable: Invalid argument");
+               return -EINVAL;
+       }
+
+       ep->is_isoc = 0;
+       ep->is_in = 0;
+
+       if (maxpacket <= 8)
+               ept_cfg = USBA_BF(EPT_SIZE, USBA_EPT_SIZE_8);
+       else
+               /* LSB is bit 1, not 0 */
+               ept_cfg = USBA_BF(EPT_SIZE, fls(maxpacket - 1) - 3);
+
+       DBG(DBG_HW, "%s: EPT_SIZE = %lu (maxpacket = %lu)\n",
+           ep->ep.name, ept_cfg, maxpacket);
+
+       if (usb_endpoint_dir_in(desc)) {
+               ep->is_in = 1;
+               ept_cfg |= USBA_EPT_DIR_IN;
+       }
+
+       switch (usb_endpoint_type(desc)) {
+       case USB_ENDPOINT_XFER_CONTROL:
+               ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL);
+               ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE);
+               break;
+       case USB_ENDPOINT_XFER_ISOC:
+               if (!ep->can_isoc) {
+                       DBG(DBG_ERR, "ep_enable: %s is not isoc capable\n",
+                           ep->ep.name);
+                       return -EINVAL;
+               }
+
+               /*
+                * Bits 11:12 specify number of _additional_
+                * transactions per microframe.
+                */
+               nr_trans = ((usb_endpoint_maxp(desc) >> 11) & 3) + 1;
+               if (nr_trans > 3)
+                       return -EINVAL;
+
+               ep->is_isoc = 1;
+               ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_ISO);
+
+               /*
+                * Do triple-buffering on high-bandwidth iso endpoints.
+                */
+               if (nr_trans > 1 && ep->nr_banks == 3)
+                       ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_TRIPLE);
+               else
+                       ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE);
+               ept_cfg |= USBA_BF(NB_TRANS, nr_trans);
+               break;
+       case USB_ENDPOINT_XFER_BULK:
+               ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK);
+               ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE);
+               break;
+       case USB_ENDPOINT_XFER_INT:
+               ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_INT);
+               ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE);
+               break;
+       }
+
+       spin_lock_irqsave(&ep->udc->lock, flags);
+
+       ep->desc = desc;
+       ep->ep.maxpacket = maxpacket;
+
+       usba_ep_writel(ep, CFG, ept_cfg);
+       usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE);
+
+       usba_writel(udc, INT_ENB,
+                   (usba_readl(udc, INT_ENB)
+                    | USBA_BF(EPT_INT, 1 << ep->index)));
+
+       spin_unlock_irqrestore(&udc->lock, flags);
+
+       DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index,
+           (unsigned long)usba_ep_readl(ep, CFG));
+       DBG(DBG_HW, "INT_ENB after init: %#08lx\n",
+           (unsigned long)usba_readl(udc, INT_ENB));
+
+       return 0;
+}
+
+static int usba_ep_disable(struct usb_ep *_ep)
+{
+       struct usba_ep *ep = to_usba_ep(_ep);
+       struct usba_udc *udc = ep->udc;
+       LIST_HEAD(req_list);
+       unsigned long flags;
+
+       DBG(DBG_GADGET, "ep_disable: %s\n", ep->ep.name);
+
+       spin_lock_irqsave(&udc->lock, flags);
+
+       if (!ep->desc) {
+               spin_unlock_irqrestore(&udc->lock, flags);
+               /* REVISIT because this driver disables endpoints in
+                * reset_all_endpoints() before calling disconnect(),
+                * most gadget drivers would trigger this non-error ...
+                */
+               if (udc->gadget.speed != USB_SPEED_UNKNOWN)
+                       DBG(DBG_ERR, "ep_disable: %s not enabled\n",
+                           ep->ep.name);
+               return -EINVAL;
+       }
+       ep->desc = NULL;
+
+       list_splice_init(&ep->queue, &req_list);
+       usba_ep_writel(ep, CFG, 0);
+       usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE);
+       usba_writel(udc, INT_ENB,
+                   usba_readl(udc, INT_ENB) &
+                   ~USBA_BF(EPT_INT, 1 << ep->index));
+
+       request_complete_list(ep, &req_list, -ESHUTDOWN);
+
+       spin_unlock_irqrestore(&udc->lock, flags);
+
+       return 0;
+}
+
+static struct usb_request *
+usba_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
+{
+       struct usba_request *req;
+
+       DBG(DBG_GADGET, "ep_alloc_request: %p, 0x%x\n", _ep, gfp_flags);
+
+       req = malloc(sizeof(struct usba_request));
+       if (!req)
+               return NULL;
+
+       INIT_LIST_HEAD(&req->queue);
+
+       return &req->req;
+}
+
+static void
+usba_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct usba_request *req = to_usba_req(_req);
+
+       DBG(DBG_GADGET, "ep_free_request: %p, %p\n", _ep, _req);
+
+       free(req);
+}
+
+static int
+usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+{
+       struct usba_request *req = to_usba_req(_req);
+       struct usba_ep *ep = to_usba_ep(_ep);
+       struct usba_udc *udc = ep->udc;
+       unsigned long flags;
+       int ret;
+
+       DBG(DBG_GADGET | DBG_QUEUE | DBG_REQ, "%s: queue req %p, len %u\n",
+           ep->ep.name, req, _req->length);
+
+       if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN ||
+           !ep->desc)
+               return -ESHUTDOWN;
+
+       req->submitted = 0;
+       req->using_dma = 0;
+       req->last_transaction = 0;
+
+       _req->status = -EINPROGRESS;
+       _req->actual = 0;
+
+       /* May have received a reset since last time we checked */
+       ret = -ESHUTDOWN;
+       spin_lock_irqsave(&udc->lock, flags);
+       if (ep->desc) {
+               list_add_tail(&req->queue, &ep->queue);
+
+               if ((!ep_is_control(ep) && ep->is_in) ||
+                   (ep_is_control(ep) && (ep->state == DATA_STAGE_IN ||
+                   ep->state == STATUS_STAGE_IN)))
+                       usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
+               else
+                       usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY);
+
+               ret = 0;
+       }
+       spin_unlock_irqrestore(&udc->lock, flags);
+
+       return ret;
+}
+
+static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct usba_ep *ep = to_usba_ep(_ep);
+       struct usba_request *req = to_usba_req(_req);
+
+       DBG(DBG_GADGET | DBG_QUEUE, "ep_dequeue: %s, req %p\n",
+           ep->ep.name, req);
+
+       /*
+        * Errors should stop the queue from advancing until the
+        * completion function returns.
+        */
+       list_del_init(&req->queue);
+
+       request_complete(ep, req, -ECONNRESET);
+
+       /* Process the next request if any */
+       submit_next_request(ep);
+
+       return 0;
+}
+
+static int usba_ep_set_halt(struct usb_ep *_ep, int value)
+{
+       struct usba_ep *ep = to_usba_ep(_ep);
+       unsigned long flags;
+       int ret = 0;
+
+       DBG(DBG_GADGET, "endpoint %s: %s HALT\n", ep->ep.name,
+           value ? "set" : "clear");
+
+       if (!ep->desc) {
+               DBG(DBG_ERR, "Attempted to halt uninitialized ep %s\n",
+                   ep->ep.name);
+               return -ENODEV;
+       }
+
+       if (ep->is_isoc) {
+               DBG(DBG_ERR, "Attempted to halt isochronous ep %s\n",
+                   ep->ep.name);
+               return -ENOTTY;
+       }
+
+       spin_lock_irqsave(&udc->lock, flags);
+
+       /*
+        * We can't halt IN endpoints while there are still data to be
+        * transferred
+        */
+       if (!list_empty(&ep->queue) ||
+           ((value && ep->is_in && (usba_ep_readl(ep, STA) &
+           USBA_BF(BUSY_BANKS, -1L))))) {
+               ret = -EAGAIN;
+       } else {
+               if (value)
+                       usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL);
+               else
+                       usba_ep_writel(ep, CLR_STA,
+                                      USBA_FORCE_STALL | USBA_TOGGLE_CLR);
+               usba_ep_readl(ep, STA);
+       }
+
+       spin_unlock_irqrestore(&udc->lock, flags);
+
+       return ret;
+}
+
+static int usba_ep_fifo_status(struct usb_ep *_ep)
+{
+       struct usba_ep *ep = to_usba_ep(_ep);
+
+       return USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA));
+}
+
+static void usba_ep_fifo_flush(struct usb_ep *_ep)
+{
+       struct usba_ep *ep = to_usba_ep(_ep);
+       struct usba_udc *udc = ep->udc;
+
+       usba_writel(udc, EPT_RST, 1 << ep->index);
+}
+
+static const struct usb_ep_ops usba_ep_ops = {
+       .enable         = usba_ep_enable,
+       .disable        = usba_ep_disable,
+       .alloc_request  = usba_ep_alloc_request,
+       .free_request   = usba_ep_free_request,
+       .queue          = usba_ep_queue,
+       .dequeue        = usba_ep_dequeue,
+       .set_halt       = usba_ep_set_halt,
+       .fifo_status    = usba_ep_fifo_status,
+       .fifo_flush     = usba_ep_fifo_flush,
+};
+
+static int usba_udc_get_frame(struct usb_gadget *gadget)
+{
+       struct usba_udc *udc = to_usba_udc(gadget);
+
+       return USBA_BFEXT(FRAME_NUMBER, usba_readl(udc, FNUM));
+}
+
+static int usba_udc_wakeup(struct usb_gadget *gadget)
+{
+       struct usba_udc *udc = to_usba_udc(gadget);
+       unsigned long flags;
+       u32 ctrl;
+       int ret = -EINVAL;
+
+       spin_lock_irqsave(&udc->lock, flags);
+       if (udc->devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
+               ctrl = usba_readl(udc, CTRL);
+               usba_writel(udc, CTRL, ctrl | USBA_REMOTE_WAKE_UP);
+               ret = 0;
+       }
+       spin_unlock_irqrestore(&udc->lock, flags);
+
+       return ret;
+}
+
+static int
+usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered)
+{
+       struct usba_udc *udc = to_usba_udc(gadget);
+       unsigned long flags;
+
+       spin_lock_irqsave(&udc->lock, flags);
+       if (is_selfpowered)
+               udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED;
+       else
+               udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
+       spin_unlock_irqrestore(&udc->lock, flags);
+
+       return 0;
+}
+
+static const struct usb_gadget_ops usba_udc_ops = {
+       .get_frame              = usba_udc_get_frame,
+       .wakeup                 = usba_udc_wakeup,
+       .set_selfpowered        = usba_udc_set_selfpowered,
+};
+
+static struct usb_endpoint_descriptor usba_ep0_desc = {
+       .bLength = USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType = USB_DT_ENDPOINT,
+       .bEndpointAddress = 0,
+       .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
+       .wMaxPacketSize = cpu_to_le16(64),
+       /* FIXME: I have no idea what to put here */
+       .bInterval = 1,
+};
+
+/*
+ * Called with interrupts disabled and udc->lock held.
+ */
+static void reset_all_endpoints(struct usba_udc *udc)
+{
+       struct usba_ep *ep;
+       struct usba_request *req, *tmp_req;
+
+       usba_writel(udc, EPT_RST, ~0UL);
+
+       ep = to_usba_ep(udc->gadget.ep0);
+       list_for_each_entry_safe(req, tmp_req, &ep->queue, queue) {
+               list_del_init(&req->queue);
+               request_complete(ep, req, -ECONNRESET);
+       }
+
+       /* NOTE:  normally, the next call to the gadget driver is in
+        * charge of disabling endpoints... usually disconnect().
+        * The exception would be entering a high speed test mode.
+        *
+        * FIXME remove this code ... and retest thoroughly.
+        */
+       list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+               if (ep->desc) {
+                       spin_unlock(&udc->lock);
+                       usba_ep_disable(&ep->ep);
+                       spin_lock(&udc->lock);
+               }
+       }
+}
+
+static struct usba_ep *get_ep_by_addr(struct usba_udc *udc, u16 wIndex)
+{
+       struct usba_ep *ep;
+
+       if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
+               return to_usba_ep(udc->gadget.ep0);
+
+       list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+               u8 bEndpointAddress;
+
+               if (!ep->desc)
+                       continue;
+               bEndpointAddress = ep->desc->bEndpointAddress;
+               if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
+                       continue;
+               if ((bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
+                               == (wIndex & USB_ENDPOINT_NUMBER_MASK))
+                       return ep;
+       }
+
+       return NULL;
+}
+
+/* Called with interrupts disabled and udc->lock held */
+static inline void set_protocol_stall(struct usba_udc *udc, struct usba_ep *ep)
+{
+       usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL);
+       ep->state = WAIT_FOR_SETUP;
+}
+
+static inline int is_stalled(struct usba_udc *udc, struct usba_ep *ep)
+{
+       if (usba_ep_readl(ep, STA) & USBA_FORCE_STALL)
+               return 1;
+       return 0;
+}
+
+static inline void set_address(struct usba_udc *udc, unsigned int addr)
+{
+       u32 regval;
+
+       DBG(DBG_BUS, "setting address %u...\n", addr);
+       regval = usba_readl(udc, CTRL);
+       regval = USBA_BFINS(DEV_ADDR, addr, regval);
+       usba_writel(udc, CTRL, regval);
+}
+
+static int do_test_mode(struct usba_udc *udc)
+{
+       static const char test_packet_buffer[] = {
+               /* JKJKJKJK * 9 */
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               /* JJKKJJKK * 8 */
+               0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+               /* JJKKJJKK * 8 */
+               0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+               /* JJJJJJJKKKKKKK * 8 */
+               0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+               /* JJJJJJJK * 8 */
+               0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD,
+               /* {JKKKKKKK * 10}, JK */
+               0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E
+       };
+       struct usba_ep *ep;
+       int test_mode;
+
+       test_mode = udc->test_mode;
+
+       /* Start from a clean slate */
+       reset_all_endpoints(udc);
+
+       switch (test_mode) {
+       case 0x0100:
+               /* Test_J */
+               usba_writel(udc, TST, USBA_TST_J_MODE);
+               DBG(DBG_ALL, "Entering Test_J mode...\n");
+               break;
+       case 0x0200:
+               /* Test_K */
+               usba_writel(udc, TST, USBA_TST_K_MODE);
+               DBG(DBG_ALL, "Entering Test_K mode...\n");
+               break;
+       case 0x0300:
+               /*
+                * Test_SE0_NAK: Force high-speed mode and set up ep0
+                * for Bulk IN transfers
+                */
+               ep = &udc->usba_ep[0];
+               usba_writel(udc, TST,
+                           USBA_BF(SPEED_CFG, USBA_SPEED_CFG_FORCE_HIGH));
+               usba_ep_writel(ep, CFG,
+                              USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64)
+                              | USBA_EPT_DIR_IN
+                              | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK)
+                              | USBA_BF(BK_NUMBER, 1));
+               if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) {
+                       set_protocol_stall(udc, ep);
+                       DBG(DBG_ALL, "Test_SE0_NAK: ep0 not mapped\n");
+               } else {
+                       usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE);
+                       DBG(DBG_ALL, "Entering Test_SE0_NAK mode...\n");
+               }
+               break;
+       case 0x0400:
+               /* Test_Packet */
+               ep = &udc->usba_ep[0];
+               usba_ep_writel(ep, CFG,
+                              USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64)
+                              | USBA_EPT_DIR_IN
+                              | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK)
+                              | USBA_BF(BK_NUMBER, 1));
+               if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) {
+                       set_protocol_stall(udc, ep);
+                       DBG(DBG_ALL, "Test_Packet: ep0 not mapped\n");
+               } else {
+                       usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE);
+                       usba_writel(udc, TST, USBA_TST_PKT_MODE);
+                       memcpy(ep->fifo, test_packet_buffer,
+                              sizeof(test_packet_buffer));
+                       usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+                       DBG(DBG_ALL, "Entering Test_Packet mode...\n");
+               }
+               break;
+       default:
+               DBG(DBG_ERR, "Invalid test mode: 0x%04x\n", test_mode);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* Avoid overly long expressions */
+static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq)
+{
+       if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
+               return true;
+       return false;
+}
+
+static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq)
+{
+       if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE))
+               return true;
+       return false;
+}
+
+static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
+{
+       if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT))
+               return true;
+       return false;
+}
+
+static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
+               struct usb_ctrlrequest *crq)
+{
+       int retval = 0;
+
+       switch (crq->bRequest) {
+       case USB_REQ_GET_STATUS: {
+               u16 status;
+
+               if (crq->bRequestType == (USB_DIR_IN | USB_RECIP_DEVICE)) {
+                       status = cpu_to_le16(udc->devstatus);
+               } else if (crq->bRequestType
+                               == (USB_DIR_IN | USB_RECIP_INTERFACE)) {
+                       status = cpu_to_le16(0);
+               } else if (crq->bRequestType
+                               == (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
+                       struct usba_ep *target;
+
+                       target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
+                       if (!target)
+                               goto stall;
+
+                       status = 0;
+                       if (is_stalled(udc, target))
+                               status |= cpu_to_le16(1);
+               } else {
+                       goto delegate;
+               }
+
+               /* Write directly to the FIFO. No queueing is done. */
+               if (crq->wLength != cpu_to_le16(sizeof(status)))
+                       goto stall;
+               ep->state = DATA_STAGE_IN;
+               __raw_writew(status, ep->fifo);
+               usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY);
+               break;
+       }
+
+       case USB_REQ_CLEAR_FEATURE: {
+               if (crq->bRequestType == USB_RECIP_DEVICE) {
+                       if (feature_is_dev_remote_wakeup(crq))
+                               udc->devstatus
+                                       &= ~(1 << USB_DEVICE_REMOTE_WAKEUP);
+                       else
+                               /* Can't CLEAR_FEATURE TEST_MODE */
+                               goto stall;
+               } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
+                       struct usba_ep *target;
+
+                       if (crq->wLength != cpu_to_le16(0) ||
+                           !feature_is_ep_halt(crq))
+                               goto stall;
+                       target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
+                       if (!target)
+                               goto stall;
+
+                       usba_ep_writel(target, CLR_STA, USBA_FORCE_STALL);
+                       if (target->index != 0)
+                               usba_ep_writel(target, CLR_STA,
+                                              USBA_TOGGLE_CLR);
+               } else {
+                       goto delegate;
+               }
+
+               send_status(udc, ep);
+               break;
+       }
+
+       case USB_REQ_SET_FEATURE: {
+               if (crq->bRequestType == USB_RECIP_DEVICE) {
+                       if (feature_is_dev_test_mode(crq)) {
+                               send_status(udc, ep);
+                               ep->state = STATUS_STAGE_TEST;
+                               udc->test_mode = le16_to_cpu(crq->wIndex);
+                               return 0;
+                       } else if (feature_is_dev_remote_wakeup(crq)) {
+                               udc->devstatus |= 1 << USB_DEVICE_REMOTE_WAKEUP;
+                       } else {
+                               goto stall;
+                       }
+               } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
+                       struct usba_ep *target;
+
+                       if (crq->wLength != cpu_to_le16(0) ||
+                           !feature_is_ep_halt(crq))
+                               goto stall;
+
+                       target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
+                       if (!target)
+                               goto stall;
+
+                       usba_ep_writel(target, SET_STA, USBA_FORCE_STALL);
+               } else {
+                       goto delegate;
+               }
+
+               send_status(udc, ep);
+               break;
+       }
+
+       case USB_REQ_SET_ADDRESS:
+               if (crq->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE))
+                       goto delegate;
+
+               set_address(udc, le16_to_cpu(crq->wValue));
+               send_status(udc, ep);
+               ep->state = STATUS_STAGE_ADDR;
+               break;
+
+       default:
+delegate:
+               spin_unlock(&udc->lock);
+               retval = udc->driver->setup(&udc->gadget, crq);
+               spin_lock(&udc->lock);
+       }
+
+       return retval;
+
+stall:
+       DBG(DBG_ALL, "%s: Invalid setup request: %02x.%02x v%04x i%04x l%d\n",
+           ep->ep.name, crq->bRequestType, crq->bRequest,
+           le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex),
+           le16_to_cpu(crq->wLength));
+       set_protocol_stall(udc, ep);
+
+       return -1;
+}
+
+static void usba_control_irq(struct usba_udc *udc, struct usba_ep *ep)
+{
+       struct usba_request *req;
+       u32 epstatus;
+       u32 epctrl;
+
+restart:
+       epstatus = usba_ep_readl(ep, STA);
+       epctrl = usba_ep_readl(ep, CTL);
+
+       DBG(DBG_INT, "%s [%d]: s/%08x c/%08x\n",
+           ep->ep.name, ep->state, epstatus, epctrl);
+
+       req = NULL;
+       if (!list_empty(&ep->queue))
+               req = list_entry(ep->queue.next,
+                                struct usba_request, queue);
+
+       if ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) {
+               if (req->submitted)
+                       next_fifo_transaction(ep, req);
+               else
+                       submit_request(ep, req);
+
+               if (req->last_transaction) {
+                       usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
+                       usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE);
+               }
+               goto restart;
+       }
+       if ((epstatus & epctrl) & USBA_TX_COMPLETE) {
+               usba_ep_writel(ep, CLR_STA, USBA_TX_COMPLETE);
+
+               switch (ep->state) {
+               case DATA_STAGE_IN:
+                       usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY);
+                       usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+                       ep->state = STATUS_STAGE_OUT;
+                       break;
+               case STATUS_STAGE_ADDR:
+                       /* Activate our new address */
+                       usba_writel(udc, CTRL, (usba_readl(udc, CTRL)
+                                               | USBA_FADDR_EN));
+                       usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+                       ep->state = WAIT_FOR_SETUP;
+                       break;
+               case STATUS_STAGE_IN:
+                       if (req) {
+                               list_del_init(&req->queue);
+                               request_complete(ep, req, 0);
+                               submit_next_request(ep);
+                       }
+                       usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+                       ep->state = WAIT_FOR_SETUP;
+                       break;
+               case STATUS_STAGE_TEST:
+                       usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE);
+                       ep->state = WAIT_FOR_SETUP;
+                       if (do_test_mode(udc))
+                               set_protocol_stall(udc, ep);
+                       break;
+               default:
+                       DBG(DBG_ALL, "%s: TXCOMP: Invalid endpoint state %d\n",
+                           ep->ep.name, ep->state);
+                       set_protocol_stall(udc, ep);
+                       break;
+               }
+
+               goto restart;
+       }
+       if ((epstatus & epctrl) & USBA_RX_BK_RDY) {
+               switch (ep->state) {
+               case STATUS_STAGE_OUT:
+                       usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+                       usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+
+                       if (req) {
+                               list_del_init(&req->queue);
+                               request_complete(ep, req, 0);
+                       }
+                       ep->state = WAIT_FOR_SETUP;
+                       break;
+
+               case DATA_STAGE_OUT:
+                       receive_data(ep);
+                       break;
+
+               default:
+                       usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+                       usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+                       DBG(DBG_ALL, "%s: RXRDY: Invalid endpoint state %d\n",
+                           ep->ep.name, ep->state);
+                       set_protocol_stall(udc, ep);
+                       break;
+               }
+
+               goto restart;
+       }
+       if (epstatus & USBA_RX_SETUP) {
+               union {
+                       struct usb_ctrlrequest crq;
+                       unsigned long data[2];
+               } crq;
+               unsigned int pkt_len;
+               int ret;
+
+               if (ep->state != WAIT_FOR_SETUP) {
+                       /*
+                        * Didn't expect a SETUP packet at this
+                        * point. Clean up any pending requests (which
+                        * may be successful).
+                        */
+                       int status = -EPROTO;
+
+                       /*
+                        * RXRDY and TXCOMP are dropped when SETUP
+                        * packets arrive.  Just pretend we received
+                        * the status packet.
+                        */
+                       if (ep->state == STATUS_STAGE_OUT ||
+                           ep->state == STATUS_STAGE_IN) {
+                               usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY);
+                               status = 0;
+                       }
+
+                       if (req) {
+                               list_del_init(&req->queue);
+                               request_complete(ep, req, status);
+                       }
+               }
+
+               pkt_len = USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA));
+               DBG(DBG_HW, "Packet length: %u\n", pkt_len);
+               if (pkt_len != sizeof(crq)) {
+                       DBG(DBG_ALL, "udc: Invalid length %u (expected %zu)\n",
+                           pkt_len, sizeof(crq));
+                       set_protocol_stall(udc, ep);
+                       return;
+               }
+
+               DBG(DBG_FIFO, "Copying ctrl request from 0x%p:\n", ep->fifo);
+               memcpy(crq.data, ep->fifo, sizeof(crq));
+
+               /* Free up one bank in the FIFO so that we can
+                * generate or receive a reply right away. */
+               usba_ep_writel(ep, CLR_STA, USBA_RX_SETUP);
+
+               if (crq.crq.bRequestType & USB_DIR_IN) {
+                       /*
+                        * The USB 2.0 spec states that "if wLength is
+                        * zero, there is no data transfer phase."
+                        * However, testusb #14 seems to actually
+                        * expect a data phase even if wLength = 0...
+                        */
+                       ep->state = DATA_STAGE_IN;
+               } else {
+                       if (crq.crq.wLength != cpu_to_le16(0))
+                               ep->state = DATA_STAGE_OUT;
+                       else
+                               ep->state = STATUS_STAGE_IN;
+               }
+
+               ret = -1;
+               if (ep->index == 0) {
+                       ret = handle_ep0_setup(udc, ep, &crq.crq);
+               } else {
+                       spin_unlock(&udc->lock);
+                       ret = udc->driver->setup(&udc->gadget, &crq.crq);
+                       spin_lock(&udc->lock);
+               }
+
+               DBG(DBG_BUS, "req %02x.%02x, length %d, state %d, ret %d\n",
+                   crq.crq.bRequestType, crq.crq.bRequest,
+                   le16_to_cpu(crq.crq.wLength), ep->state, ret);
+
+               if (ret < 0) {
+                       /* Let the host know that we failed */
+                       set_protocol_stall(udc, ep);
+               }
+       }
+}
+
+static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep)
+{
+       struct usba_request *req;
+       u32 epstatus;
+       u32 epctrl;
+
+       epstatus = usba_ep_readl(ep, STA);
+       epctrl = usba_ep_readl(ep, CTL);
+
+       DBG(DBG_INT, "%s: interrupt, status: 0x%08x\n", ep->ep.name, epstatus);
+
+       while ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) {
+               DBG(DBG_BUS, "%s: TX PK ready\n", ep->ep.name);
+
+               if (list_empty(&ep->queue)) {
+                       DBG(DBG_INT, "ep_irq: queue empty\n");
+                       usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY);
+                       return;
+               }
+
+               req = list_entry(ep->queue.next, struct usba_request, queue);
+
+               if (req->submitted)
+                       next_fifo_transaction(ep, req);
+               else
+                       submit_request(ep, req);
+
+               if (req->last_transaction) {
+                       list_del_init(&req->queue);
+                       submit_next_request(ep);
+                       request_complete(ep, req, 0);
+               }
+
+               epstatus = usba_ep_readl(ep, STA);
+               epctrl = usba_ep_readl(ep, CTL);
+       }
+
+       if ((epstatus & epctrl) & USBA_RX_BK_RDY) {
+               DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name);
+               receive_data(ep);
+               usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
+       }
+}
+
+static int usba_udc_irq(struct usba_udc *udc)
+{
+       u32 status, ep_status;
+
+       spin_lock(&udc->lock);
+
+       status = usba_readl(udc, INT_STA);
+       DBG(DBG_INT, "irq, status=%#08x\n", status);
+
+       if (status & USBA_DET_SUSPEND) {
+               usba_writel(udc, INT_CLR, USBA_DET_SUSPEND);
+               DBG(DBG_BUS, "Suspend detected\n");
+               if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+                   udc->driver && udc->driver->suspend) {
+                       spin_unlock(&udc->lock);
+                       udc->driver->suspend(&udc->gadget);
+                       spin_lock(&udc->lock);
+               }
+       }
+
+       if (status & USBA_WAKE_UP) {
+               usba_writel(udc, INT_CLR, USBA_WAKE_UP);
+               DBG(DBG_BUS, "Wake Up CPU detected\n");
+       }
+
+       if (status & USBA_END_OF_RESUME) {
+               usba_writel(udc, INT_CLR, USBA_END_OF_RESUME);
+               DBG(DBG_BUS, "Resume detected\n");
+               if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+                   udc->driver && udc->driver->resume) {
+                       spin_unlock(&udc->lock);
+                       udc->driver->resume(&udc->gadget);
+                       spin_lock(&udc->lock);
+               }
+       }
+
+       ep_status = USBA_BFEXT(EPT_INT, status);
+       if (ep_status) {
+               int i;
+
+               for (i = 0; i < USBA_NR_ENDPOINTS; i++)
+                       if (ep_status & (1 << i)) {
+                               if (ep_is_control(&udc->usba_ep[i]))
+                                       usba_control_irq(udc, &udc->usba_ep[i]);
+                               else
+                                       usba_ep_irq(udc, &udc->usba_ep[i]);
+                       }
+       }
+
+       if (status & USBA_END_OF_RESET) {
+               struct usba_ep *ep0;
+
+               usba_writel(udc, INT_CLR, USBA_END_OF_RESET);
+               reset_all_endpoints(udc);
+
+               if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+                   udc->driver->disconnect) {
+                       udc->gadget.speed = USB_SPEED_UNKNOWN;
+                       spin_unlock(&udc->lock);
+                       udc->driver->disconnect(&udc->gadget);
+                       spin_lock(&udc->lock);
+               }
+
+               if (status & USBA_HIGH_SPEED)
+                       udc->gadget.speed = USB_SPEED_HIGH;
+               else
+                       udc->gadget.speed = USB_SPEED_FULL;
+
+               ep0 = &udc->usba_ep[0];
+               ep0->desc = &usba_ep0_desc;
+               ep0->state = WAIT_FOR_SETUP;
+               usba_ep_writel(ep0, CFG,
+                              (USBA_BF(EPT_SIZE, EP0_EPT_SIZE)
+                               | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL)
+                               | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE)));
+               usba_ep_writel(ep0, CTL_ENB,
+                              USBA_EPT_ENABLE | USBA_RX_SETUP);
+               usba_writel(udc, INT_ENB,
+                           (usba_readl(udc, INT_ENB)
+                            | USBA_BF(EPT_INT, 1)
+                            | USBA_DET_SUSPEND
+                            | USBA_END_OF_RESUME));
+
+               /*
+                * Unclear why we hit this irregularly, e.g. in usbtest,
+                * but it's clearly harmless...
+                */
+               if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED))
+                       DBG(DBG_ALL, "ODD: EP0 configuration is invalid!\n");
+       }
+
+       spin_unlock(&udc->lock);
+
+       return 0;
+}
+
+static int atmel_usba_start(struct usba_udc *udc)
+{
+       udc->devstatus = 1 << USB_DEVICE_SELF_POWERED;
+
+       udc->vbus_prev = 0;
+
+       /* If Vbus is present, enable the controller and wait for reset */
+       if (vbus_is_present(udc) && udc->vbus_prev == 0) {
+               usba_writel(udc, CTRL, USBA_ENABLE_MASK);
+               usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
+       }
+
+       return 0;
+}
+
+static int atmel_usba_stop(struct usba_udc *udc)
+{
+       udc->gadget.speed = USB_SPEED_UNKNOWN;
+       reset_all_endpoints(udc);
+
+       /* This will also disable the DP pullup */
+       usba_writel(udc, CTRL, USBA_DISABLE_MASK);
+
+       return 0;
+}
+
+static struct usba_udc controller = {
+       .regs = (unsigned *)ATMEL_BASE_UDPHS,
+       .fifo = (unsigned *)ATMEL_BASE_UDPHS_FIFO,
+       .gadget = {
+               .ops            = &usba_udc_ops,
+               .ep_list        = LIST_HEAD_INIT(controller.gadget.ep_list),
+               .speed          = USB_SPEED_HIGH,
+               .is_dualspeed   = 1,
+               .name           = "atmel_usba_udc",
+       },
+};
+
+int usb_gadget_handle_interrupts(void)
+{
+       struct usba_udc *udc = &controller;
+
+       return usba_udc_irq(udc);
+}
+
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+       struct usba_udc *udc = &controller;
+       int ret;
+
+       if (!driver || !driver->bind || !driver->setup) {
+               printf("bad paramter\n");
+               return -EINVAL;
+       }
+
+       if (udc->driver) {
+               printf("UDC already has a gadget driver\n");
+               return -EBUSY;
+       }
+
+       atmel_usba_start(udc);
+
+       udc->driver = driver;
+
+       ret = driver->bind(&udc->gadget);
+       if (ret) {
+               error("driver->bind() returned %d\n", ret);
+               udc->driver = NULL;
+       }
+
+       return ret;
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+       struct usba_udc *udc = &controller;
+
+       if (!driver || !driver->unbind || !driver->disconnect) {
+               error("bad paramter\n");
+               return -EINVAL;
+       }
+
+       driver->disconnect(&udc->gadget);
+       driver->unbind(&udc->gadget);
+       udc->driver = NULL;
+
+       atmel_usba_stop(udc);
+
+       return 0;
+}
+
+static struct usba_ep *usba_udc_pdata(struct usba_platform_data *pdata,
+                                     struct usba_udc *udc)
+{
+       struct usba_ep *eps;
+       int i;
+
+       eps = malloc(sizeof(struct usba_ep) * pdata->num_ep);
+       if (!eps) {
+               error("failed to alloc eps\n");
+               return NULL;
+       }
+
+       udc->gadget.ep0 = &eps[0].ep;
+
+       INIT_LIST_HEAD(&udc->gadget.ep_list);
+       INIT_LIST_HEAD(&eps[0].ep.ep_list);
+
+       for (i = 0; i < pdata->num_ep; i++) {
+               struct usba_ep *ep = &eps[i];
+
+               ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
+               ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
+               ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
+               ep->ep.ops = &usba_ep_ops;
+               ep->ep.name = pdata->ep[i].name;
+               ep->ep.maxpacket = pdata->ep[i].fifo_size;
+               ep->fifo_size = ep->ep.maxpacket;
+               ep->udc = udc;
+               INIT_LIST_HEAD(&ep->queue);
+               ep->nr_banks = pdata->ep[i].nr_banks;
+               ep->index = pdata->ep[i].index;
+               ep->can_dma = pdata->ep[i].can_dma;
+               ep->can_isoc = pdata->ep[i].can_isoc;
+               if (i)
+                       list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+       };
+
+       return eps;
+}
+
+int usba_udc_probe(struct usba_platform_data *pdata)
+{
+       struct usba_udc *udc;
+
+       udc = &controller;
+
+       udc->usba_ep = usba_udc_pdata(pdata, udc);
+
+       return 0;
+}
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
new file mode 100644 (file)
index 0000000..92e462d
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Register definition for Atmel USBA high speed USB device controller
+ * [Original from Linux kernel: drivers/usb/gadget/atmel_usba_udc.h]
+ *
+ * Copyright (C) 2005-2013 Atmel Corporation
+ *                        Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __LINUX_USB_GADGET_USBA_UDC_H__
+#define __LINUX_USB_GADGET_USBA_UDC_H__
+
+/* USB register offsets */
+#define USBA_CTRL                              0x0000
+#define USBA_FNUM                              0x0004
+#define USBA_INT_ENB                           0x0010
+#define USBA_INT_STA                           0x0014
+#define USBA_INT_CLR                           0x0018
+#define USBA_EPT_RST                           0x001c
+#define USBA_TST                               0x00e0
+
+/* USB endpoint register offsets */
+#define USBA_EPT_CFG                           0x0000
+#define USBA_EPT_CTL_ENB                       0x0004
+#define USBA_EPT_CTL_DIS                       0x0008
+#define USBA_EPT_CTL                           0x000c
+#define USBA_EPT_SET_STA                       0x0014
+#define USBA_EPT_CLR_STA                       0x0018
+#define USBA_EPT_STA                           0x001c
+
+/* USB DMA register offsets */
+#define USBA_DMA_NXT_DSC                       0x0000
+#define USBA_DMA_ADDRESS                       0x0004
+#define USBA_DMA_CONTROL                       0x0008
+#define USBA_DMA_STATUS                                0x000c
+
+/* Bitfields in CTRL */
+#define USBA_DEV_ADDR_OFFSET                   0
+#define USBA_DEV_ADDR_SIZE                     7
+#define USBA_FADDR_EN                          (1 <<  7)
+#define USBA_EN_USBA                           (1 <<  8)
+#define USBA_DETACH                            (1 <<  9)
+#define USBA_REMOTE_WAKE_UP                    (1 << 10)
+#define USBA_PULLD_DIS                         (1 << 11)
+
+#if defined(CONFIG_AVR32)
+#define USBA_ENABLE_MASK                       USBA_EN_USBA
+#define USBA_DISABLE_MASK                      0
+#elif defined(CONFIG_AT91FAMILY)
+#define USBA_ENABLE_MASK                       (USBA_EN_USBA | USBA_PULLD_DIS)
+#define USBA_DISABLE_MASK                      USBA_DETACH
+#endif /* CONFIG_ARCH_AT91 */
+
+/* Bitfields in FNUM */
+#define USBA_MICRO_FRAME_NUM_OFFSET            0
+#define USBA_MICRO_FRAME_NUM_SIZE              3
+#define USBA_FRAME_NUMBER_OFFSET               3
+#define USBA_FRAME_NUMBER_SIZE                 11
+#define USBA_FRAME_NUM_ERROR                   (1 << 31)
+
+/* Bitfields in INT_ENB/INT_STA/INT_CLR */
+#define USBA_HIGH_SPEED                                (1 <<  0)
+#define USBA_DET_SUSPEND                       (1 <<  1)
+#define USBA_MICRO_SOF                         (1 <<  2)
+#define USBA_SOF                               (1 <<  3)
+#define USBA_END_OF_RESET                      (1 <<  4)
+#define USBA_WAKE_UP                           (1 <<  5)
+#define USBA_END_OF_RESUME                     (1 <<  6)
+#define USBA_UPSTREAM_RESUME                   (1 <<  7)
+#define USBA_EPT_INT_OFFSET                    8
+#define USBA_EPT_INT_SIZE                      16
+#define USBA_DMA_INT_OFFSET                    24
+#define USBA_DMA_INT_SIZE                      8
+
+/* Bitfields in EPT_RST */
+#define USBA_RST_OFFSET                                0
+#define USBA_RST_SIZE                          16
+
+/* Bitfields in USBA_TST */
+#define USBA_SPEED_CFG_OFFSET                  0
+#define USBA_SPEED_CFG_SIZE                    2
+#define USBA_TST_J_MODE                                (1 <<  2)
+#define USBA_TST_K_MODE                                (1 <<  3)
+#define USBA_TST_PKT_MODE                      (1 <<  4)
+#define USBA_OPMODE2                           (1 <<  5)
+
+/* Bitfields in EPT_CFG */
+#define USBA_EPT_SIZE_OFFSET                   0
+#define USBA_EPT_SIZE_SIZE                     3
+#define USBA_EPT_DIR_IN                                (1 <<  3)
+#define USBA_EPT_TYPE_OFFSET                   4
+#define USBA_EPT_TYPE_SIZE                     2
+#define USBA_BK_NUMBER_OFFSET                  6
+#define USBA_BK_NUMBER_SIZE                    2
+#define USBA_NB_TRANS_OFFSET                   8
+#define USBA_NB_TRANS_SIZE                     2
+#define USBA_EPT_MAPPED                                (1 << 31)
+
+/* Bitfields in EPT_CTL/EPT_CTL_ENB/EPT_CTL_DIS */
+#define USBA_EPT_ENABLE                                (1 <<  0)
+#define USBA_AUTO_VALID                                (1 <<  1)
+#define USBA_INTDIS_DMA                                (1 <<  3)
+#define USBA_NYET_DIS                          (1 <<  4)
+#define USBA_DATAX_RX                          (1 <<  6)
+#define USBA_MDATA_RX                          (1 <<  7)
+/* Bits 8-15 and 31 enable interrupts for respective bits in EPT_STA */
+#define USBA_BUSY_BANK_IE                      (1 << 18)
+
+/* Bitfields in EPT_SET_STA/EPT_CLR_STA/EPT_STA */
+#define USBA_FORCE_STALL                       (1 <<  5)
+#define USBA_TOGGLE_CLR                                (1 <<  6)
+#define USBA_TOGGLE_SEQ_OFFSET                 6
+#define USBA_TOGGLE_SEQ_SIZE                   2
+#define USBA_ERR_OVFLW                         (1 <<  8)
+#define USBA_RX_BK_RDY                         (1 <<  9)
+#define USBA_KILL_BANK                         (1 <<  9)
+#define USBA_TX_COMPLETE                       (1 << 10)
+#define USBA_TX_PK_RDY                         (1 << 11)
+#define USBA_ISO_ERR_TRANS                     (1 << 11)
+#define USBA_RX_SETUP                          (1 << 12)
+#define USBA_ISO_ERR_FLOW                      (1 << 12)
+#define USBA_STALL_SENT                                (1 << 13)
+#define USBA_ISO_ERR_CRC                       (1 << 13)
+#define USBA_ISO_ERR_NBTRANS                   (1 << 13)
+#define USBA_NAK_IN                            (1 << 14)
+#define USBA_ISO_ERR_FLUSH                     (1 << 14)
+#define USBA_NAK_OUT                           (1 << 15)
+#define USBA_CURRENT_BANK_OFFSET               16
+#define USBA_CURRENT_BANK_SIZE                 2
+#define USBA_BUSY_BANKS_OFFSET                 18
+#define USBA_BUSY_BANKS_SIZE                   2
+#define USBA_BYTE_COUNT_OFFSET                 20
+#define USBA_BYTE_COUNT_SIZE                   11
+#define USBA_SHORT_PACKET                      (1 << 31)
+
+/* Bitfields in DMA_CONTROL */
+#define USBA_DMA_CH_EN                         (1 <<  0)
+#define USBA_DMA_LINK                          (1 <<  1)
+#define USBA_DMA_END_TR_EN                     (1 <<  2)
+#define USBA_DMA_END_BUF_EN                    (1 <<  3)
+#define USBA_DMA_END_TR_IE                     (1 <<  4)
+#define USBA_DMA_END_BUF_IE                    (1 <<  5)
+#define USBA_DMA_DESC_LOAD_IE                  (1 <<  6)
+#define USBA_DMA_BURST_LOCK                    (1 <<  7)
+#define USBA_DMA_BUF_LEN_OFFSET                        16
+#define USBA_DMA_BUF_LEN_SIZE                  16
+
+/* Bitfields in DMA_STATUS */
+#define USBA_DMA_CH_ACTIVE                     (1 <<  1)
+#define USBA_DMA_END_TR_ST                     (1 <<  4)
+#define USBA_DMA_END_BUF_ST                    (1 <<  5)
+#define USBA_DMA_DESC_LOAD_ST                  (1 <<  6)
+
+/* Constants for SPEED_CFG */
+#define USBA_SPEED_CFG_NORMAL                  0
+#define USBA_SPEED_CFG_FORCE_HIGH              2
+#define USBA_SPEED_CFG_FORCE_FULL              3
+
+/* Constants for EPT_SIZE */
+#define USBA_EPT_SIZE_8                                0
+#define USBA_EPT_SIZE_16                       1
+#define USBA_EPT_SIZE_32                       2
+#define USBA_EPT_SIZE_64                       3
+#define USBA_EPT_SIZE_128                      4
+#define USBA_EPT_SIZE_256                      5
+#define USBA_EPT_SIZE_512                      6
+#define USBA_EPT_SIZE_1024                     7
+
+/* Constants for EPT_TYPE */
+#define USBA_EPT_TYPE_CONTROL                  0
+#define USBA_EPT_TYPE_ISO                      1
+#define USBA_EPT_TYPE_BULK                     2
+#define USBA_EPT_TYPE_INT                      3
+
+/* Constants for BK_NUMBER */
+#define USBA_BK_NUMBER_ZERO                    0
+#define USBA_BK_NUMBER_ONE                     1
+#define USBA_BK_NUMBER_DOUBLE                  2
+#define USBA_BK_NUMBER_TRIPLE                  3
+
+/* Bit manipulation macros */
+#define USBA_BF(name, value)                                   \
+       (((value) & ((1 << USBA_##name##_SIZE) - 1))            \
+        << USBA_##name##_OFFSET)
+#define USBA_BFEXT(name, value)                                        \
+       (((value) >> USBA_##name##_OFFSET)                      \
+        & ((1 << USBA_##name##_SIZE) - 1))
+#define USBA_BFINS(name, value, old)                           \
+       (((old) & ~(((1 << USBA_##name##_SIZE) - 1)             \
+                   << USBA_##name##_OFFSET))                   \
+        | USBA_BF(name, value))
+
+/* Register access macros */
+#define usba_readl(udc, reg)                                   \
+       __raw_readl((udc)->regs + USBA_##reg)
+#define usba_writel(udc, reg, value)                           \
+       __raw_writel((value), (udc)->regs + USBA_##reg)
+#define usba_ep_readl(ep, reg)                                 \
+       __raw_readl((ep)->ep_regs + USBA_EPT_##reg)
+#define usba_ep_writel(ep, reg, value)                         \
+       __raw_writel((value), (ep)->ep_regs + USBA_EPT_##reg)
+#define usba_dma_readl(ep, reg)                                        \
+       __raw_readl((ep)->dma_regs + USBA_DMA_##reg)
+#define usba_dma_writel(ep, reg, value)                                \
+       __raw_writel((value), (ep)->dma_regs + USBA_DMA_##reg)
+
+/* Calculate base address for a given endpoint or DMA controller */
+#define USBA_EPT_BASE(x)       (0x100 + (x) * 0x20)
+#define USBA_DMA_BASE(x)       (0x300 + (x) * 0x10)
+#define USBA_FIFO_BASE(x)      ((x) << 16)
+
+/* Synth parameters */
+#define USBA_NR_ENDPOINTS      7
+
+#define EP0_FIFO_SIZE          64
+#define EP0_EPT_SIZE           USBA_EPT_SIZE_64
+#define EP0_NR_BANKS           1
+
+#define DBG_ERR                0x0001  /* report all error returns */
+#define DBG_HW         0x0002  /* debug hardware initialization */
+#define DBG_GADGET     0x0004  /* calls to/from gadget driver */
+#define DBG_INT                0x0008  /* interrupts */
+#define DBG_BUS                0x0010  /* report changes in bus state */
+#define DBG_QUEUE      0x0020  /* debug request queue processing */
+#define DBG_FIFO       0x0040  /* debug FIFO contents */
+#define DBG_DMA                0x0080  /* debug DMA handling */
+#define DBG_REQ                0x0100  /* print out queued request length */
+#define DBG_ALL                0xffff
+#define DBG_NONE       0x0000
+
+#define DEBUG_LEVEL    (DBG_ERR)
+
+#define DBG(level, fmt, ...)                                   \
+       do {                                                    \
+               if ((level) & DEBUG_LEVEL)                      \
+                       debug("udc: " fmt, ## __VA_ARGS__);     \
+       } while (0)
+
+enum usba_ctrl_state {
+       WAIT_FOR_SETUP,
+       DATA_STAGE_IN,
+       DATA_STAGE_OUT,
+       STATUS_STAGE_IN,
+       STATUS_STAGE_OUT,
+       STATUS_STAGE_ADDR,
+       STATUS_STAGE_TEST,
+};
+
+struct usba_dma_desc {
+       dma_addr_t next;
+       dma_addr_t addr;
+       u32 ctrl;
+};
+
+struct usba_ep {
+       int                                     state;
+       void                                    *ep_regs;
+       void                                    *dma_regs;
+       void                                    *fifo;
+       struct usb_ep                           ep;
+       struct usba_udc                         *udc;
+
+       struct list_head                        queue;
+
+       u16                                     fifo_size;
+       u8                                      nr_banks;
+       u8                                      index;
+       unsigned int                            can_dma:1;
+       unsigned int                            can_isoc:1;
+       unsigned int                            is_isoc:1;
+       unsigned int                            is_in:1;
+
+       const struct usb_endpoint_descriptor    *desc;
+};
+
+struct usba_request {
+       struct usb_request                      req;
+       struct list_head                        queue;
+
+       u32                                     ctrl;
+
+       unsigned int                            submitted:1;
+       unsigned int                            last_transaction:1;
+       unsigned int                            using_dma:1;
+       unsigned int                            mapped:1;
+};
+
+struct usba_udc {
+       void *regs;
+       void *fifo;
+
+       struct usb_gadget gadget;
+       struct usb_gadget_driver *driver;
+       struct platform_device *pdev;
+       int irq;
+       int vbus_pin;
+       int vbus_pin_inverted;
+       int num_ep;
+       struct usba_ep *usba_ep;
+
+       u16 devstatus;
+
+       u16 test_mode;
+       int vbus_prev;
+};
+
+static inline struct usba_ep *to_usba_ep(struct usb_ep *ep)
+{
+       return container_of(ep, struct usba_ep, ep);
+}
+
+static inline struct usba_request *to_usba_req(struct usb_request *req)
+{
+       return container_of(req, struct usba_request, req);
+}
+
+static inline struct usba_udc *to_usba_udc(struct usb_gadget *gadget)
+{
+       return container_of(gadget, struct usba_udc, gadget);
+}
+
+#define ep_is_control(ep)      ((ep)->index == 0)
+#define ep_is_idle(ep)         ((ep)->state == EP_STATE_IDLE)
+
+#endif /* __LINUX_USB_GADGET_USBA_UDC_H */
index f563afe787dfd179a6e0f5da95e09f81bcf35ea8..014a6791c17139e5cc04830ab576f304a0b51392 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <asm/unaligned.h>
 #include <asm/errno.h>
 #include <linux/list.h>
 #include <linux/string.h>
@@ -86,7 +87,8 @@ int usb_gadget_config_buf(
        /* config descriptor first */
        if (length < USB_DT_CONFIG_SIZE || !desc)
                return -EINVAL;
-       *cp = *config;
+       /* config need not be aligned */
+       memcpy(cp, config, sizeof(*cp));
 
        /* then interface/endpoint/class/vendor/... */
        len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8 *)buf,
@@ -100,7 +102,7 @@ int usb_gadget_config_buf(
        /* patch up the config descriptor */
        cp->bLength = USB_DT_CONFIG_SIZE;
        cp->bDescriptorType = USB_DT_CONFIG;
-       cp->wTotalLength = cpu_to_le16(len);
+       put_unaligned_le16(len, &cp->wTotalLength);
        cp->bmAttributes |= USB_CONFIG_ATT_ONE;
        return len;
 }
index 579893cbffb5ca5ea25e52f14abe3981d0d6d09b..700d5fbfb2ffa4f77faf24fea40bae5b5e32b486 100644 (file)
@@ -849,9 +849,10 @@ static struct usb_gadget_strings   stringtab = {
 };
 
 /*============================================================================*/
-static u8 control_req[USB_BUFSIZ];
+DEFINE_CACHE_ALIGN_BUFFER(u8, control_req, USB_BUFSIZ);
+
 #if defined(CONFIG_USB_ETH_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-static u8 status_req[STATUS_BYTECOUNT] __attribute__ ((aligned(4)));
+DEFINE_CACHE_ALIGN_BUFFER(u8, status_req, STATUS_BYTECOUNT);
 #endif
 
 
index 34a4dde5aa7e3bdad1a3e5398da479b659de4e8e..cc2c45567b6cb2e0830d1275b144a75186bd2dfa 100644 (file)
@@ -82,7 +82,4 @@ struct dfu_function_descriptor {
        __le16                          wTransferSize;
        __le16                          bcdDFUVersion;
 } __packed;
-
-/* configuration-specific linkup */
-int dfu_add(struct usb_configuration *c);
 #endif /* __F_DFU_H_ */
index a3e05a872a7bdd157ddcad653a32cc9f97f391d5..40868c034e42fcde8416d407552e38e2e2daf75b 100644 (file)
@@ -7,7 +7,6 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <errno.h>
 #include <common.h>
 #include <malloc.h>
 
 #include <part.h>
 
 #include <g_dnl.h>
-#include "f_dfu.h"
+#include <usb_mass_storage.h>
+#include <dfu.h>
 
 #include "gadget_chips.h"
 #include "composite.c"
-#include "f_mass_storage.c"
 
 /*
  * One needs to define the following:
index fdad739724eacb545817ebaf8128bdba96a82c91..3ae04c0253b694c32e310824627301b395e9ffe0 100644 (file)
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
 #endif
 
+/*
+ * EHCI spec page 20 says that the HC may take up to 16 uFrames (= 4ms) to halt.
+ * Let's time out after 8 to have a little safety margin on top of that.
+ */
+#define HCHALT_TIMEOUT (8 * 1000)
+
 static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
 
 #define ALIGN_END_ADDR(type, ptr, size)                        \
@@ -190,6 +196,36 @@ out:
        return ret;
 }
 
+static int ehci_shutdown(struct ehci_ctrl *ctrl)
+{
+       int i, ret = 0;
+       uint32_t cmd, reg;
+
+       cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+       cmd &= ~(CMD_PSE | CMD_ASE);
+       ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+       ret = handshake(&ctrl->hcor->or_usbsts, STS_ASS | STS_PSS, 0,
+               100 * 1000);
+
+       if (!ret) {
+               for (i = 0; i < CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS; i++) {
+                       reg = ehci_readl(&ctrl->hcor->or_portsc[i]);
+                       reg |= EHCI_PS_SUSP;
+                       ehci_writel(&ctrl->hcor->or_portsc[i], reg);
+               }
+
+               cmd &= ~CMD_RUN;
+               ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+               ret = handshake(&ctrl->hcor->or_usbsts, STS_HALT, STS_HALT,
+                       HCHALT_TIMEOUT);
+       }
+
+       if (ret)
+               puts("EHCI failed to shut down host controller.\n");
+
+       return ret;
+}
+
 static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
 {
        uint32_t delta, next;
@@ -808,6 +844,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
                        }
                        break;
                case USB_PORT_FEAT_TEST:
+                       ehci_shutdown(ctrl);
                        reg &= ~(0xf << 16);
                        reg |= ((le16_to_cpu(req->index) >> 8) & 0xf) << 16;
                        ehci_writel(status_reg, reg);
@@ -878,6 +915,7 @@ unknown:
 
 int usb_lowlevel_stop(int index)
 {
+       ehci_shutdown(&ehcic[index]);
        return ehci_hcd_stop(index);
 }
 
index 41a8126b3e2ef2b3ff8954a21d32c91c9f60c966..708fa124a21489f4b9ed46a24fc2dce0ffc4970e 100644 (file)
@@ -417,8 +417,12 @@ static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer)
 
                /* Set TXPKTRDY bit */
                csr = readw(&musbr->txcsr);
-               writew(csr | MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY,
-                                       &musbr->txcsr);
+                       
+               csr |= MUSB_CSR0_TXPKTRDY;
+#if !defined(CONFIG_SOC_DM365)
+               csr |= MUSB_CSR0_H_DIS_PING;
+#endif
+               writew(csr, &musbr->txcsr);
                result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
                if (result < 0)
                        break;
@@ -439,8 +443,10 @@ static int ctrlreq_out_status_phase(struct usb_device *dev)
 
        /* Set the StatusPkt bit */
        csr = readw(&musbr->txcsr);
-       csr |= (MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY |
-                       MUSB_CSR0_H_STATUSPKT);
+       csr |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_H_STATUSPKT);
+#if !defined(CONFIG_SOC_DM365)
+       csr |= MUSB_CSR0_H_DIS_PING;
+#endif
        writew(csr, &musbr->txcsr);
 
        /* Wait until TXPKTRDY bit is cleared */
@@ -457,7 +463,10 @@ static int ctrlreq_in_status_phase(struct usb_device *dev)
        int result;
 
        /* Set the StatusPkt bit and ReqPkt bit */
-       csr = MUSB_CSR0_H_DIS_PING | MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
+       csr = MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
+#if !defined(CONFIG_SOC_DM365)
+       csr |= MUSB_CSR0_H_DIS_PING;
+#endif
        writew(csr, &musbr->txcsr);
        result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT);
 
index 28e7e6978825fa26db46ad82ce2d6503ffa06eba..a2d52e77703f94ebeb963d8e62213d556a78d5b7 100644 (file)
@@ -154,10 +154,10 @@ The MAC address can be stored in four locations:
 
 -Boot environmental variable in Flash <- can not change, without
                                          re-flashing U-boot.
-U-Boot environental variable          <- can not change, without
+U-Boot environmental variable         <- can not change, without
                                          resetting board/U-Boot
-LAN91C111 Registers                   <- volitle
-LAN91C111 EEPROM                      <- Non Volitle
+LAN91C111 Registers                   <- volatile
+LAN91C111 EEPROM                      <- Non-volatile
 
 If you have not activated the network, and do not have a hardcoded
 or pre-assigned MAC address in U-boot, the environmental variables
diff --git a/fs/fs.c b/fs/fs.c
index 99e516a44d82dc74f868a5636a021c3c81718db1..be1855d1291f217b19720ae0faa45076eb0cc5ac 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -231,7 +231,7 @@ int fs_write(const char *filename, ulong addr, int offset, int len)
 }
 
 int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
-               int fstype, int cmdline_base)
+               int fstype)
 {
        unsigned long addr;
        const char *addr_str;
@@ -250,7 +250,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                return 1;
 
        if (argc >= 4) {
-               addr = simple_strtoul(argv[3], NULL, cmdline_base);
+               addr = simple_strtoul(argv[3], NULL, 16);
        } else {
                addr_str = getenv("loadaddr");
                if (addr_str != NULL)
@@ -268,11 +268,11 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                }
        }
        if (argc >= 6)
-               bytes = simple_strtoul(argv[5], NULL, cmdline_base);
+               bytes = simple_strtoul(argv[5], NULL, 16);
        else
                bytes = 0;
        if (argc >= 7)
-               pos = simple_strtoul(argv[6], NULL, cmdline_base);
+               pos = simple_strtoul(argv[6], NULL, 16);
        else
                pos = 0;
 
@@ -313,7 +313,7 @@ int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 }
 
 int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
-               int fstype, int cmdline_base)
+               int fstype)
 {
        unsigned long addr;
        const char *filename;
@@ -329,10 +329,10 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                return 1;
 
        filename = argv[3];
-       addr = simple_strtoul(argv[4], NULL, cmdline_base);
-       bytes = simple_strtoul(argv[5], NULL, cmdline_base);
+       addr = simple_strtoul(argv[4], NULL, 16);
+       bytes = simple_strtoul(argv[5], NULL, 16);
        if (argc >= 7)
-               pos = simple_strtoul(argv[6], NULL, cmdline_base);
+               pos = simple_strtoul(argv[6], NULL, 16);
        else
                pos = 0;
 
index 4d2a56d0dea327cffd5f805d84132a655a7c760d..bed43168fe5c2f3d84aa117c0383720ece5b7620 100644 (file)
@@ -383,7 +383,7 @@ int setenv_hex(const char *varname, ulong value);
 /**
  * setenv_addr - Set an environment variable to an address in hex
  *
- * @varname:   Environmet variable to set
+ * @varname:   Environment variable to set
  * @addr:      Value to set it to
  * @return 0 if ok, 1 on error
  */
@@ -596,6 +596,12 @@ void ddr_enable_ecc(unsigned int dram_size);
 #endif
 #endif
 
+/*
+ * Return the current value of a monotonically increasing microsecond timer.
+ * Granularity may be larger than 1us if hardware does not support this.
+ */
+ulong timer_get_us(void);
+
 /* $(CPU)/cpu.c */
 static inline int cpumask_next(int cpu, unsigned int mask)
 {
@@ -1017,10 +1023,10 @@ static inline phys_addr_t map_to_sysmem(void *ptr)
  * of a function scoped static buffer.  It can not be used to create a cache
  * line aligned global buffer.
  */
-#define PAD_COUNT(s, pad) ((s - 1) / pad + 1)
+#define PAD_COUNT(s, pad) (((s) - 1) / (pad) + 1)
 #define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
 #define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad)           \
-       char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align)  \
+       char __##name[ROUND(PAD_SIZE((size) * sizeof(type), pad), align)  \
                      + (align - 1)];                                   \
                                                                        \
        type *name = (type *) ALIGN((uintptr_t)__##name, align)
index 905bacfa969d367e0da30f5894edf8267c2480f2..862614b5c25b3d6fbf8c8bc7d1e65b9c3483b652 100644 (file)
@@ -354,10 +354,10 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 #define CONFIG_SYS_I2C_FSL
 #define CONFIG_SYS_FSL_I2C_SPEED       400000
 #define CONFIG_SYS_FSL_I2C_SLAVE       0x7F
-#define CONFIG_SYS_FSL_I2C_OFFSET      0x3000
+#define CONFIG_SYS_FSL_I2C_OFFSET      0x118000
 #define CONFIG_SYS_FSL_I2C2_SPEED      400000
 #define CONFIG_SYS_FSL_I2C2_SLAVE      0x7F
-#define CONFIG_SYS_FSL_I2C2_OFFSET     0x3100
+#define CONFIG_SYS_FSL_I2C2_OFFSET     0x118100
 
 /*
  * RapidIO
index 2f06ca2ead601be5e28176dd12023bf1767570f8..f746e485489051b58b09910b5981b381f0d7bc78 100644 (file)
        "loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \
        "importbootenv=echo Importing environment from mmc ...; " \
                "env import -t $loadaddr $filesize\0" \
+       "dfu_alt_info_ram=" DFU_ALT_INFO_RAM "\0" \
        "ramargs=setenv bootargs console=${console} " \
                "${optargs} " \
                "root=${ramroot} " \
        "run mmcboot;" \
        "setenv mmcdev 1; " \
        "setenv bootpart 1:2; " \
-       "setenv mmcroot /dev/mmcblk1p2 ro; " \
        "run mmcboot;" \
        "run nandboot;"
 
        "kernel part 0 8;" \
        "rootfs part 0 9"
 #endif
+#define CONFIG_DFU_RAM
+#define DFU_ALT_INFO_RAM \
+       "kernel ram 0x80200000 0xD80000;" \
+       "fdt ram 0x80F80000 0x80000;" \
+       "ramdisk ram 0x81000000 0x4000000"
 
 /*
  * Default to using SPI for environment, etc.
index e63d7c4ab6e79495a0551c7626a0b20dd282682d..98455060396a6105d0df5b1ff6a1319e3aee31a3 100644 (file)
 #define CONFIG_SPI_FLASH
 #define CONFIG_SPI_FLASH_STMICRO
 #define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_CMD_SF
 #define CONFIG_DAVINCI_SPI
 #define CONFIG_SYS_SPI_BASE            DAVINCI_SPI1_BASE
 #define CONFIG_SYS_SPI_CLK             clk_get(DAVINCI_SPI1_CLKID)
 #undef CONFIG_CMD_IMLS
 #undef CONFIG_CMD_FLASH
 #define CONFIG_CMD_SPI
-#define CONFIG_CMD_SF
 #define CONFIG_CMD_SAVEENV
 #endif
 
index 7b120de2133ce028d23a9098c318e8c93f84706b..51e0e801a2c34ba5be34dfb94f57ad8313e137d8 100644 (file)
 #define CONFIG_PHYLIB
 #define CONFIG_PHY_ADDR                        2
 
+/* SPI */
+#undef CONFIG_OMAP3_SPI
+#define CONFIG_TI_QSPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_SPANSION
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_TI_SPI_MMAP
+#define CONFIG_SF_DEFAULT_SPEED                48000000
+#define CONFIG_DEFAULT_SPI_MODE                SPI_MODE_3
+
+/* SPI SPL */
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_SPI_LOAD
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_BUS             0
+#define CONFIG_SPL_SPI_CS              0
+#define CONFIG_SYS_SPI_U_BOOT_OFFS     0x20000
+
 #endif /* __CONFIG_DRA7XX_EVM_H */
index c2d04a21c7c9302758d037bc5429bc5ceca081a2..7321b60c2fb1f42ffc562bec883f51e8ca9d62d8 100644 (file)
 
 #define CONFIG_ENV_IS_IN_FLASH 1
 #define CONFIG_ENV_SECT_SIZE   0x20000 /* Size of one Flash sector */
-#define CONFIG_ENV_SIZE                CONFIG_ENV_SECT_SIZE    /* Use one Flash sector for enviroment  */
+#define CONFIG_ENV_SIZE                CONFIG_ENV_SECT_SIZE    /* Use one Flash sector for environment */
 #define CONFIG_ENV_ADDR                0xFFFC0000
 #define CONFIG_ENV_OFFSET              0       /* starting right at the beginning  */
 
index a82987d6a09f5a05e7c33c1efd6085fadd92982a..733023049f22940848803ac7bd58a8f27a4b0917 100644 (file)
@@ -18,6 +18,7 @@
 #define CONFIG_CMD_ASKENV
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_DEFAULTENV_VARS
+#define CONFIG_CMD_GREPENV
 #define CONFIG_CMD_ECHO
 #define CONFIG_CMD_IMMAP
 #define CONFIG_CMD_MII
index 0ff866a8966ce3603978235a937961181f05fb2d..5e075c8dd2a0bfe023cd978640ef8f61a1944cb4 100644 (file)
 #define CONFIG_DTT_LM75                /* ON Semi's LM75 */
 #define CONFIG_DTT_SENSORS     {0, 1, 2, 3}    /* Sensor addresses */
 #define CONFIG_SYS_DTT_MAX_TEMP        70
-#define CONFIG_SYS_DTT_LOW_TEMP        -30
 #define CONFIG_SYS_DTT_HYSTERESIS      3
 #define CONFIG_SYS_DTT_BUS_NUM         1
 
index b23cb96274d3a8ec7aab0ab34e7683ba7ca77327..726c646bc5098c5e39da5658135ca57c5914376d 100644 (file)
@@ -271,7 +271,6 @@ int get_scl(void);
 #define CONFIG_DTT_LM75                        /* ON Semi's LM75               */
 #define CONFIG_DTT_SENSORS     {0}     /* Sensor addresses             */
 #define CONFIG_SYS_DTT_MAX_TEMP        70
-#define CONFIG_SYS_DTT_LOW_TEMP        -30
 #define CONFIG_SYS_DTT_HYSTERESIS      3
 #define CONFIG_SYS_DTT_BUS_NUM         2
 
index 98ba559c86d134f2158c1d047ab3a018d12c911a..eade6375cdb9c8609f09e1dc6cf11cb2e3298fbc 100644 (file)
@@ -83,7 +83,7 @@
        "partitions=" PARTS_DEFAULT "\0" \
        "optargs=\0" \
        "mmcdev=0\0" \
-       "mmcroot=/dev/mmcblk0p2 rw\0" \
+       "mmcroot=/dev/mmcblk1p2 rw\0" \
        "mmcrootfstype=ext4 rootwait\0" \
        "mmcargs=setenv bootargs console=${console} " \
                "${optargs} " \
        "importbootenv=echo Importing environment from mmc${mmcdev} ...; " \
                "env import -t ${loadaddr} ${filesize}\0" \
        "loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}\0" \
-       "mmcboot=echo Booting from mmc${mmcdev} ...; " \
-               "run mmcargs; " \
-               "bootz ${loadaddr} - ${fdtaddr}\0" \
+       "mmcboot=mmc dev ${mmcdev}; " \
+               "if mmc rescan; then " \
+                       "echo SD/MMC found on device ${mmcdev};" \
+                       "if run loadbootenv; then " \
+                               "echo Loaded environment from ${bootenv};" \
+                               "run importbootenv;" \
+                       "fi;" \
+                       "if test -n $uenvcmd; then " \
+                               "echo Running uenvcmd ...;" \
+                               "run uenvcmd;" \
+                       "fi;" \
+                       "if run loadimage; then " \
+                               "run loadfdt; " \
+                               "echo Booting from mmc${mmcdev} ...; " \
+                               "run mmcargs; " \
+                               "bootz ${loadaddr} - ${fdtaddr}; " \
+                       "fi;" \
+               "fi;\0" \
        "findfdt="\
                "if test $board_name = omap5_uevm; then " \
                        "setenv fdtfile omap5-uevm.dtb; fi; " \
 
 #define CONFIG_BOOTCOMMAND \
        "run findfdt; " \
-       "mmc dev ${mmcdev}; if mmc rescan; then " \
-               "if run loadbootscript; then " \
-                       "run bootscript; " \
-               "else " \
-                       "if run loadbootenv; then " \
-                               "run importbootenv; " \
-                       "fi;" \
-                       "if test -n ${uenvcmd}; then " \
-                               "echo Running uenvcmd ...;" \
-                               "run uenvcmd;" \
-                       "fi;" \
-               "fi;" \
-               "if run loadimage; then " \
-                       "run loadfdt; " \
-                       "run mmcboot; " \
-               "fi; " \
-       "fi"
+       "run mmcboot;" \
+       "setenv mmcdev 1; " \
+       "setenv bootpart 1:2; " \
+       "setenv mmcroot /dev/mmcblk0p2 rw; " \
+       "run mmcboot;" \
 
 
 /*
index d63d0c4f54421d72cc9a3667fcb60c6671d2bdd1..0feef1eabb40dbc3081dba1c18b5b84518cfa739 100644 (file)
 #define CONFIG_ENV_IN_OWN_SECT 1
 
 /* Define this to contain any number of null terminated strings that
- * will be part of the default enviroment compiled into the boot image.
+ * will be part of the default environment compiled into the boot image.
  */
 #define CONFIG_EXTRA_ENV_SETTINGS \
 "quiet=0\0" \
index 76fa500eddb5b137fe407ae6ce71514015def7a7..79c00684dd262d59a22cf1e0ed852035e15f79d9 100644 (file)
 #define CONFIG_USB_STORAGE
 #endif
 
+/* USB device */
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_ATMEL_USBA
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_RNDIS
+#define CONFIG_USBNET_MANUFACTURER      "Atmel SAMA5D3xEK"
+
 #if defined(CONFIG_CMD_USB) || defined(CONFIG_CMD_MMC)
 #define CONFIG_CMD_FAT
 #endif
index 65dabde54ff1a93545a91279ba1f8fe4af85e640..a6d692872cecbd6551b10d2ab30b13fc6bb69844 100644 (file)
 #define CONFIG_ATMEL_SPI0              /* SPI used for FRAM is SPI0 */
 #define FRAM_SPI_BUS           0
 #define FRAM_CS_NUM            0
-#define CONFIG_SPI_FLASH               /* RAMTRON FRAM on SPI bus */
 #define CONFIG_SPI_FRAM_RAMTRON
 #define CONFIG_SF_DEFAULT_SPEED        1000000 /* be conservative here... */
 #define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
index 47b90559d5bbe705fdba2fcc050d29d1481b6e49..b2ecf1bebea99178e70466a23c7d64e13096d568 100644 (file)
 #include <common.h>
 #include <linux/list.h>
 #include <mmc.h>
+#include <linux/usb/composite.h>
 
 enum dfu_device_type {
        DFU_DEV_MMC = 1,
        DFU_DEV_ONENAND,
        DFU_DEV_NAND,
+       DFU_DEV_RAM,
 };
 
 enum dfu_layout {
@@ -27,6 +29,12 @@ enum dfu_layout {
        DFU_FS_EXT2,
        DFU_FS_EXT3,
        DFU_FS_EXT4,
+       DFU_RAM_ADDR,
+};
+
+enum dfu_op {
+       DFU_OP_READ = 1,
+       DFU_OP_WRITE,
 };
 
 struct mmc_internal_data {
@@ -51,6 +59,11 @@ struct nand_internal_data {
        unsigned int ubi;
 };
 
+struct ram_internal_data {
+       void            *start;
+       unsigned int    size;
+};
+
 static inline unsigned int get_mmc_blk_size(int dev)
 {
        return find_mmc_device(dev)->read_bl_len;
@@ -62,7 +75,7 @@ static inline unsigned int get_mmc_blk_size(int dev)
 #define CONFIG_SYS_DFU_DATA_BUF_SIZE           (1024*1024*8)   /* 8 MiB */
 #endif
 #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
-#define CONFIG_SYS_DFU_MAX_FILE_SIZE   (4 << 20)       /* 4 MiB */
+#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
 #endif
 
 struct dfu_entity {
@@ -76,6 +89,7 @@ struct dfu_entity {
        union {
                struct mmc_internal_data mmc;
                struct nand_internal_data nand;
+               struct ram_internal_data ram;
        } data;
 
        int (*read_medium)(struct dfu_entity *dfu,
@@ -113,6 +127,7 @@ struct dfu_entity *dfu_get_entity(int alt);
 char *dfu_extract_token(char** e, int *n);
 void dfu_trigger_reset(void);
 bool dfu_reset(void);
+int dfu_init_env_entities(char *interface, int dev);
 
 int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
@@ -137,4 +152,22 @@ static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
 }
 #endif
 
+#ifdef CONFIG_DFU_RAM
+extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s);
+#else
+static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
+{
+       puts("RAM support not available!\n");
+       return -1;
+}
+#endif
+
+#ifdef CONFIG_DFU_FUNCTION
+int dfu_add(struct usb_configuration *c);
+#else
+int dfu_add(struct usb_configuration *c)
+{
+       return 0;
+}
+#endif
 #endif /* __DFU_ENTITY_H_ */
index c837bae25cda0f9a0e8d52120269a009c7a1646c..7d9403ed87588c2f254ec0a4b514fe5840eac0b9 100644 (file)
@@ -59,10 +59,10 @@ int fs_read(const char *filename, ulong addr, int offset, int len);
  * to a specific filesystem type via the fstype parameter.
  */
 int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
-               int fstype, int cmdline_base);
+               int fstype);
 int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                int fstype);
 int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
-               int fstype, int cmdline_base);
+               int fstype);
 
 #endif /* _FS_H */
index aee52e7f14a44358986351fb4080a3ef916dcb05..8dd2cc388ab0455646d866e3bd1c297280229f34 100644 (file)
@@ -85,6 +85,7 @@ struct i2stx_info {
        unsigned int bitspersample;     /* bits per sample */
        unsigned int channels;          /* audio channels */
        unsigned int base_address;      /* I2S Register Base */
+       unsigned int id;                /* I2S controller id */
 };
 
 /*
index e1943e507c023f650b687461137264e7ca36da64..dd0d23fa52a48fafab5ea2d29c56c9771ef8afc0 100644 (file)
@@ -32,8 +32,8 @@ struct part_info {
        struct list_head link;
        char *name;                     /* partition name */
        u8 auto_name;                   /* set to 1 for generated name */
-       u32 size;                       /* total size of the partition */
-       u32 offset;                     /* offset within device */
+       u64 size;                       /* total size of the partition */
+       u64 offset;                     /* offset within device */
        void *jffs2_priv;               /* used internaly by jffs2 */
        u32 mask_flags;                 /* kernel MTD mask flags */
        u32 sector_size;                /* size of sector */
@@ -44,7 +44,7 @@ struct mtdids {
        struct list_head link;
        u8 type;                        /* device type */
        u8 num;                         /* device number */
-       u32 size;                       /* device size */
+       u64 size;                       /* device size */
        char *mtd_id;                   /* linux kernel device id */
 };
 
index 765d84f5e4574eaab187be553cdbd449bf22b819..9eefaaf5f87a7de869f78a05c67bed09d56202bd 100644 (file)
@@ -596,9 +596,9 @@ const char *fdt_get_alias_namelen(const void *fdt,
                                  const char *name, int namelen);
 
 /**
- * fdt_get_alias - retreive the path referenced by a given alias
+ * fdt_get_alias - retrieve the path referenced by a given alias
  * @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
+ * @name: name of the alias to look up
  *
  * fdt_get_alias() retrieves the value of a given alias.  That is, the
  * value of the property named 'name' in the node /aliases.
index 3858f8f80f6b6cc17ea62976a78d11578025bcf8..111372c9fd08f9d0817a84e95fdae9b84fcda208 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_FB_H
 
 #include <linux/types.h>
+#include <linux/list.h>
 
 /* Definitions of frame buffers                                                */
 
index 2055584374d6277629ee3ec16b8c9a812af65483..0546565593546734d1e91b822d555fe2e25572db 100644 (file)
@@ -464,6 +464,8 @@ struct nand_buffers {
  * @pagemask:          [INTERN] page number mask = number of (pages / chip) - 1
  * @pagebuf:           [INTERN] holds the pagenumber which is currently in
  *                     data_buf.
+ * @pagebuf_bitflips:  [INTERN] holds the bitflip count for the page which is
+ *                     currently in data_buf.
  * @subpagesize:       [INTERN] holds the subpagesize
  * @onfi_version:      [INTERN] holds the chip ONFI version (BCD encoded),
  *                     non 0 if ONFI supported.
@@ -531,6 +533,7 @@ struct nand_chip {
        uint64_t chipsize;
        int pagemask;
        int pagebuf;
+       unsigned int pagebuf_bitflips;
        int subpagesize;
        uint8_t cellinfo;
        int badblockpos;
diff --git a/include/linux/usb/atmel_usba_udc.h b/include/linux/usb/atmel_usba_udc.h
new file mode 100644 (file)
index 0000000..be29ef0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Platform data definitions for Atmel USBA gadget driver
+ * [Original from Linux kernel: include/linux/usb/atmel_usba_udc.h]
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __LINUX_USB_USBA_H__
+#define __LINUX_USB_USBA_H__
+
+struct usba_ep_data {
+       char *name;
+       int index;
+       int fifo_size;
+       int nr_banks;
+       int can_dma;
+       int can_isoc;
+};
+
+struct usba_platform_data {
+       int                     num_ep;
+       struct usba_ep_data     *ep;
+};
+
+extern int usba_udc_probe(struct usba_platform_data *pdata);
+
+#endif /* __LINUX_USB_USBA_H */
index 220d06860010c5d94e16531f498369b141aa2849..a8a576316d35257b1a39fe008a6d90df522583ef 100644 (file)
@@ -18,6 +18,7 @@
 #ifndef __LINUX_USB_GADGET_H
 #define __LINUX_USB_GADGET_H
 
+#include <errno.h>
 #include <linux/list.h>
 
 struct usb_ep;
index 657b49624a90a44057aaf7f446e23a501de59e23..088797e4c6ca9d4c39a82cd6067de61c4df911a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SPDX-License-Identifier:    GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
  *
  * Additions (C) Copyright 2009 Industrie Dial Face S.p.A.
  */
index 228d77139d5682e9f249a0f8ff21e8bee9625150..214b9edc8d22144b009178af3e13829ccc92ebe5 100644 (file)
@@ -335,7 +335,11 @@ int mmc_start_init(struct mmc *mmc);
 void mmc_set_preinit(struct mmc *mmc, int preinit);
 
 #ifdef CONFIG_GENERIC_MMC
+#ifdef CONFIG_MMC_SPI
 #define mmc_host_is_spi(mmc)   ((mmc)->host_caps & MMC_MODE_SPI)
+#else
+#define mmc_host_is_spi(mmc)   0
+#endif
 struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
 #else
 int mmc_legacy_init(int verbose);
index b18b87312b7ae2d5605b2d6724e3ee56729136c2..74d06ae18a229ff7182249815ba53ec17cdfb166 100644 (file)
 #define   SDHCI_SPEC_200       1
 #define   SDHCI_SPEC_300       2
 
+#define SDHCI_GET_VERSION(x) (x->version & SDHCI_SPEC_VER_MASK)
+
 /*
  * End of controller registers.
  */
 #define SDHCI_QUIRK_NO_CD              (1 << 5)
 #define SDHCI_QUIRK_WAIT_SEND_CMD      (1 << 6)
 #define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1 << 7)
+#define SDHCI_QUIRK_USE_WIDE8          (1 << 8)
 
 /* to make gcc happy */
 struct sdhci_host;
index c0dab578bfa53533efe72cb6f6bb70c162c03d84..5164d437b9fd75819f0aca4a9394fd1532c50bdd 100644 (file)
 #define        SPI_PREAMBLE    0x80                    /* Skip preamble bytes */
 
 /* SPI transfer flags */
-#define SPI_XFER_BEGIN 0x01                    /* Assert CS before transfer */
-#define SPI_XFER_END   0x02                    /* Deassert CS after transfer */
+#define SPI_XFER_BEGIN         0x01    /* Assert CS before transfer */
+#define SPI_XFER_END           0x02    /* Deassert CS after transfer */
+#define SPI_XFER_MMAP          0x08    /* Memory Mapped start */
+#define SPI_XFER_MMAP_END      0x10    /* Memory Mapped End */
 
 /* Header byte that marks the start of the message */
 #define SPI_PREAMBLE_END_BYTE  0xec
 
-/*-----------------------------------------------------------------------
- * Representation of a SPI slave, i.e. what we're communicating with.
+/**
+ * struct spi_slave - Representation of a SPI slave
  *
  * Drivers are expected to extend this with controller-specific data.
  *
- *   bus:      ID of the bus that the slave is attached to.
- *   cs:       ID of the chip select connected to the slave.
- *   max_write_size:   If non-zero, the maximum number of bytes which can
- *             be written at once, excluding command bytes.
+ * @bus:               ID of the bus that the slave is attached to.
+ * @cs:                        ID of the chip select connected to the slave.
+ * @max_write_size:    If non-zero, the maximum number of bytes which can
+ *                     be written at once, excluding command bytes.
+ * @memory_map:                Address of read-only SPI flash access.
  */
 struct spi_slave {
-       unsigned int    bus;
-       unsigned int    cs;
+       unsigned int bus;
+       unsigned int cs;
        unsigned int max_write_size;
+       void *memory_map;
 };
 
-/*-----------------------------------------------------------------------
+/**
  * Initialization, must be called once on start up.
  *
  * TODO: I don't think we really need this.
@@ -60,10 +64,10 @@ void spi_init(void);
  * Allocate and zero all fields in the spi slave, and set the bus/chip
  * select. Use the helper macro spi_alloc_slave() to call this.
  *
- * @offset: Offset of struct spi_slave within slave structure
- * @size: Size of slave structure
- * @bus: Bus ID of the slave chip.
- * @cs: Chip select ID of the slave chip on the specified bus.
+ * @offset:    Offset of struct spi_slave within slave structure.
+ * @size:      Size of slave structure.
+ * @bus:       Bus ID of the slave chip.
+ * @cs:                Chip select ID of the slave chip on the specified bus.
  */
 void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
                         unsigned int cs);
@@ -74,10 +78,10 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
  * Allocate and zero all fields in the spi slave, and set the bus/chip
  * select.
  *
- * @_struct: Name of structure to allocate (e.g. struct tegra_spi). This
- *     structure must contain a member 'struct spi_slave *slave'.
- * @bus: Bus ID of the slave chip.
- * @cs: Chip select ID of the slave chip on the specified bus.
+ * @_struct:   Name of structure to allocate (e.g. struct tegra_spi).
+ *             This structure must contain a member 'struct spi_slave *slave'.
+ * @bus:       Bus ID of the slave chip.
+ * @cs:                Chip select ID of the slave chip on the specified bus.
  */
 #define spi_alloc_slave(_struct, bus, cs) \
        spi_do_alloc_slave(offsetof(_struct, slave), \
@@ -89,13 +93,13 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
  * Allocate and zero all fields in the spi slave, and set the bus/chip
  * select.
  *
- * @bus: Bus ID of the slave chip.
- * @cs: Chip select ID of the slave chip on the specified bus.
+ * @bus:       Bus ID of the slave chip.
+ * @cs:                Chip select ID of the slave chip on the specified bus.
  */
 #define spi_alloc_slave_base(bus, cs) \
        spi_do_alloc_slave(0, sizeof(struct spi_slave), bus, cs)
 
-/*-----------------------------------------------------------------------
+/**
  * Set up communications parameters for a SPI slave.
  *
  * This must be called once for each slave. Note that this function
@@ -103,10 +107,10 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
  * contents of spi_slave so that the hardware can be easily
  * initialized later.
  *
- *   bus:     Bus ID of the slave chip.
- *   cs:      Chip select ID of the slave chip on the specified bus.
- *   max_hz:  Maximum SCK rate in Hz.
- *   mode:    Clock polarity, clock phase and other parameters.
+ * @bus:       Bus ID of the slave chip.
+ * @cs:                Chip select ID of the slave chip on the specified bus.
+ * @max_hz:    Maximum SCK rate in Hz.
+ * @mode:      Clock polarity, clock phase and other parameters.
  *
  * Returns: A spi_slave reference that can be used in subsequent SPI
  * calls, or NULL if one or more of the parameters are not supported.
@@ -114,14 +118,14 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int mode);
 
-/*-----------------------------------------------------------------------
+/**
  * Free any memory associated with a SPI slave.
  *
- *   slave:    The SPI slave
+ * @slave:     The SPI slave
  */
 void spi_free_slave(struct spi_slave *slave);
 
-/*-----------------------------------------------------------------------
+/**
  * Claim the bus and prepare it for communication with a given slave.
  *
  * This must be called before doing any transfers with a SPI slave. It
@@ -130,25 +134,25 @@ void spi_free_slave(struct spi_slave *slave);
  * allowed to claim the same bus for several slaves without releasing
  * the bus in between.
  *
- *   slave:    The SPI slave
+ * @slave:     The SPI slave
  *
  * Returns: 0 if the bus was claimed successfully, or a negative value
  * if it wasn't.
  */
 int spi_claim_bus(struct spi_slave *slave);
 
-/*-----------------------------------------------------------------------
+/**
  * Release the SPI bus
  *
  * This must be called once for every call to spi_claim_bus() after
  * all transfers have finished. It may disable any SPI hardware as
  * appropriate.
  *
- *   slave:    The SPI slave
+ * @slave:     The SPI slave
  */
 void spi_release_bus(struct spi_slave *slave);
 
-/*-----------------------------------------------------------------------
+/**
  * SPI transfer
  *
  * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
@@ -161,19 +165,19 @@ void spi_release_bus(struct spi_slave *slave);
  * temporary variables, this is OK).
  *
  * spi_xfer() interface:
- *   slave:    The SPI slave which will be sending/receiving the data.
- *   bitlen:   How many bits to write and read.
- *   dout:     Pointer to a string of bits to send out.  The bits are
+ * @slave:     The SPI slave which will be sending/receiving the data.
+ * @bitlen:    How many bits to write and read.
+ * @dout:      Pointer to a string of bits to send out.  The bits are
  *             held in a byte array and are sent MSB first.
- *   din:      Pointer to a string of bits that will be filled in.
- *   flags:    A bitwise combination of SPI_XFER_* flags.
+ * @din:       Pointer to a string of bits that will be filled in.
+ * @flags:     A bitwise combination of SPI_XFER_* flags.
  *
- *   Returns: 0 on success, not 0 on failure
+ * Returns: 0 on success, not 0 on failure
  */
 int  spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
                void *din, unsigned long flags);
 
-/*-----------------------------------------------------------------------
+/**
  * Determine if a SPI chipselect is valid.
  * This function is provided by the board if the low-level SPI driver
  * needs it to determine if a given chipselect is actually valid.
@@ -183,7 +187,7 @@ int  spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
  */
 int  spi_cs_is_valid(unsigned int bus, unsigned int cs);
 
-/*-----------------------------------------------------------------------
+/**
  * Activate a SPI chipselect.
  * This function is provided by the board code when using a driver
  * that can't control its chipselects automatically (e.g.
@@ -192,7 +196,7 @@ int  spi_cs_is_valid(unsigned int bus, unsigned int cs);
  */
 void spi_cs_activate(struct spi_slave *slave);
 
-/*-----------------------------------------------------------------------
+/**
  * Deactivate a SPI chipselect.
  * This function is provided by the board code when using a driver
  * that can't control its chipselects automatically (e.g.
@@ -201,18 +205,18 @@ void spi_cs_activate(struct spi_slave *slave);
  */
 void spi_cs_deactivate(struct spi_slave *slave);
 
-/*-----------------------------------------------------------------------
+/**
  * Set transfer speed.
  * This sets a new speed to be applied for next spi_xfer().
- *   slave:    The SPI slave
- *   hz:       The transfer speed
+ * @slave:     The SPI slave
+ * @hz:                The transfer speed
  */
 void spi_set_speed(struct spi_slave *slave, uint hz);
 
-/*-----------------------------------------------------------------------
+/**
  * Write 8 bits, then read 8 bits.
- *   slave:    The SPI slave we're communicating with
- *   byte:     Byte to be written
+ * @slave:     The SPI slave we're communicating with
+ * @byte:      Byte to be written
  *
  * Returns: The value that was read, or a negative value on error.
  *
index bfc59aa701105eda41dd91aee9216e453eea9e88..1ff5af4dfcb446caf6f549f2c62b365090023c24 100644 (file)
@@ -1,7 +1,8 @@
 /*
- * Interface to SPI flash
+ * Common SPI flash Interface
  *
  * Copyright (C) 2008 Atmel Corporation
+ * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -10,6 +11,7 @@
  * modify it under the terms of the GNU General Public License
  * version 2 as published by the Free Software Foundation. 
  */
+
 #ifndef _SPI_FLASH_H_
 #define _SPI_FLASH_H_
 
 #include <linux/types.h>
 #include <linux/compiler.h>
 
+/**
+ * struct spi_flash - SPI flash structure
+ *
+ * @spi:               SPI slave
+ * @name:              Name of SPI flash
+ * @size:              Total flash size
+ * @page_size:         Write (page) size
+ * @sector_size:       Sector size
+ * @erase_size:                Erase size
+ * @bank_read_cmd:     Bank read cmd
+ * @bank_write_cmd:    Bank write cmd
+ * @bank_curr:         Current flash bank
+ * @poll_cmd:          Poll cmd - for flash erase/program
+ * @erase_cmd:         Erase cmd 4K, 32K, 64K
+ * @memory_map:                Address of read-only SPI flash access
+ * @read:              Flash read ops: Read len bytes at offset into buf
+ *                     Supported cmds: Fast Array Read
+ * @write:             Flash write ops: Write len bytes from buf into offeset
+ *                     Supported cmds: Page Program
+ * @erase:             Flash erase ops: Erase len bytes from offset
+ *                     Supported cmds: Sector erase 4K, 32K, 64K
+ * return 0 - Sucess, 1 - Failure
+ */
 struct spi_flash {
        struct spi_slave *spi;
+       const char *name;
 
-       const char      *name;
-
-       /* Total flash size */
-       u32             size;
-       /* Write (page) size */
-       u32             page_size;
-       /* Erase (sector) size */
-       u32             sector_size;
+       u32 size;
+       u32 page_size;
+       u32 sector_size;
+       u32 erase_size;
 #ifdef CONFIG_SPI_FLASH_BAR
-       /* Bank read cmd */
-       u8              bank_read_cmd;
-       /* Bank write cmd */
-       u8              bank_write_cmd;
-       /* Current flash bank */
-       u8              bank_curr;
+       u8 bank_read_cmd;
+       u8 bank_write_cmd;
+       u8 bank_curr;
 #endif
-       /* Poll cmd - for flash erase/program */
-       u8              poll_cmd;
+       u8 poll_cmd;
+       u8 erase_cmd;
 
-       void *memory_map;       /* Address of read-only SPI flash access */
-       int             (*read)(struct spi_flash *flash, u32 offset,
-                               size_t len, void *buf);
-       int             (*write)(struct spi_flash *flash, u32 offset,
-                               size_t len, const void *buf);
-       int             (*erase)(struct spi_flash *flash, u32 offset,
-                               size_t len);
+       void *memory_map;
+       int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);
+       int (*write)(struct spi_flash *flash, u32 offset, size_t len,
+                       const void *buf);
+       int (*erase)(struct spi_flash *flash, u32 offset, size_t len);
 };
 
-/**
- * spi_flash_do_alloc - Allocate a new spi flash structure
- *
- * The structure is allocated and cleared with default values for
- * read, write and erase, which the caller can modify. The caller must set
- * up size, page_size and sector_size.
- *
- * Use the helper macro spi_flash_alloc() to call this.
- *
- * @offset: Offset of struct spi_slave within slave structure
- * @size: Size of slave structure
- * @spi: SPI slave
- * @name: Name of SPI flash device
- */
-void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi,
-                        const char *name);
-
-/**
- * spi_flash_alloc - Allocate a new SPI flash structure
- *
- * @_struct: Name of structure to allocate (e.g. struct ramtron_spi_fram). This
- *     structure must contain a member 'struct spi_flash *flash'.
- * @spi: SPI slave
- * @name: Name of SPI flash device
- */
-#define spi_flash_alloc(_struct, spi, name) \
-       spi_flash_do_alloc(offsetof(_struct, flash), sizeof(_struct), \
-                               spi, name)
-
-/**
- * spi_flash_alloc_base - Allocate a new SPI flash structure with no private data
- *
- * @spi: SPI slave
- * @name: Name of SPI flash device
- */
-#define spi_flash_alloc_base(spi, name) \
-       spi_flash_do_alloc(0, sizeof(struct spi_flash), spi, name)
-
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int spi_mode);
 void spi_flash_free(struct spi_flash *flash);
index 35cdcc3d8c7ae77d500f4ca7de85f2a2993a08d4..e08deb4ddf179c31914add65c078ff6f0ed3f083 100644 (file)
@@ -11,6 +11,7 @@
 #define SECTOR_SIZE            0x200
 
 #include <mmc.h>
+#include <linux/usb/composite.h>
 
 struct ums_device {
        struct mmc *mmc;
@@ -39,4 +40,12 @@ extern struct ums_board_info *board_ums_init(unsigned int,
 extern int usb_gadget_handle_interrupts(void);
 extern int fsg_main_thread(void *);
 
+#ifdef CONFIG_USB_GADGET_MASS_STORAGE
+int fsg_add(struct usb_configuration *c);
+#else
+int fsg_add(struct usb_configuration *c)
+{
+       return 0;
+}
+#endif
 #endif /* __USB_MASS_STORAGE_H__ */
index 644330a17e8ce7a6bdb8f0112094d5c1e884435e..c5a2b08becf4e9e0ebfac9708f178b8575812ffe 100644 (file)
@@ -817,7 +817,7 @@ int himport_r(struct hsearch_data *htab,
         * size of 8 per entry (= safety factor of ~5) should provide enough
         * safety margin for any existing environment definitions and still
         * allow for more than enough dynamic additions. Note that the
-        * "size" argument is supposed to give the maximum enviroment size
+        * "size" argument is supposed to give the maximum environment size
         * (CONFIG_ENV_SIZE).  This heuristics will result in
         * unreasonably large numbers (and thus memory footprint) for
         * big flash environments (>8,000 entries for 64 KB
index da37d66bfadfe936c768f3da610789f06c7e9852..cca1a26235462cb96b6c3bc9cfb5bcaabcf91f1a 100644 (file)
@@ -22,7 +22,7 @@
  *
  * LCD backlight is not enabled if temperature values are not within
  * allowed ranges (-30 .. + 80). The brightness of backlite can be
- * controlled by setting "brightness" enviroment variable. Default value is 50%
+ * controlled by setting "brightness" environment variable. Default value is 50%
  *
  * See the list of all parameters in the sysmon_table below
  */
index 734ada65a8bf716578b526f3bb8e79aeee8758be..f63f27867323cb870641470e3cc88f89d1973293 100644 (file)
@@ -629,6 +629,28 @@ It is common when refactoring code for the rodata to decrease as the text size
 increases, and vice versa.
 
 
+Providing 'make' flags
+======================
+
+U-Boot's build system supports a few flags (such as BUILD_TAG) which affect
+the build product. These flags can be specified in the buildman settings
+file. They can also be useful when building U-Boot against other open source
+software.
+
+[make-flags]
+at91-boards=ENABLE_AT91_TEST=1
+snapper9260=${at91-boards} BUILD_TAG=442
+snapper9g45=${at91-boards} BUILD_TAG=443
+
+This will use 'make ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9260
+and 'make ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9g45. A special
+variable ${target} is available to access the target name (snapper9260 and
+snapper9g20 in this case). Variables are resolved recursively.
+
+It is expected that any variables added are dealt with in U-Boot's
+config.mk file and documented in the README.
+
+
 Other options
 =============
 
index a3888964175a75d60e98d41c2f1e50cc8c20d832..1d3db206bda10508d906bfb3a5a01e26ea81423e 100644 (file)
@@ -5,16 +5,17 @@
 
 class Board:
     """A particular board that we can build"""
-    def __init__(self, target, arch, cpu, board_name, vendor, soc, options):
+    def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options):
         """Create a new board type.
 
         Args:
-            target: Target name (use make <target>_config to configure)
+            status: define whether the board is 'Active' or 'Orphaned'
             arch: Architecture name (e.g. arm)
             cpu: Cpu name (e.g. arm1136)
-            board_name: Name of board (e.g. integrator)
-            vendor: Name of vendor (e.g. armltd)
             soc: Name of SOC, or '' if none (e.g. mx31)
+            vendor: Name of vendor (e.g. armltd)
+            board_name: Name of board (e.g. integrator)
+            target: Target name (use make <target>_config to configure)
             options: board-specific options (e.g. integratorcp:CM1136)
         """
         self.target = target
@@ -63,8 +64,10 @@ class Boards:
                 for upto in range(len(fields)):
                     if fields[upto] == '-':
                         fields[upto] = ''
-                while len(fields) < 9:
+                while len(fields) < 8:
                     fields.append('')
+                if len(fields) > 8:
+                    fields = fields[:8]
 
                 board = Board(*fields)
                 self.AddBoard(board)
index c80113056c8c248e593fae9610ec03bf5b337c78..916479866c4e12605df134d7944afde1633128dc 100644 (file)
@@ -36,9 +36,6 @@ def GetItems(section):
         return settings.items(section)
     except ConfigParser.NoSectionError as e:
         print e
-        print ("Warning: No tool chains - please add a [toolchain] section "
-                "to your buildman config file %s. See README for details" %
-                config_fname)
         return []
     except:
         raise
index 29da67a54e79e147491666aae9606d99fdaad3e0..4a2d753c218c6675aad3a84c08fb0163bed9002e 100644 (file)
@@ -253,6 +253,7 @@ class BuilderThread(threading.Thread):
                     args.extend(['-j', str(self.builder.num_jobs)])
                 config_args = ['%s_config' % brd.target]
                 config_out = ''
+                args.extend(self.builder.toolchains.GetMakeArguments(brd))
 
                 # If we need to reconfigure, do that now
                 if do_config:
index 6fba2f292a03b136bcef989e0f1767258d59302d..43895b87ea729d02b675a68b38e26784b21ef57c 100755 (executable)
@@ -32,6 +32,19 @@ import toolchain
 
 def RunTests():
     import test
+    import doctest
+
+    result = unittest.TestResult()
+    for module in ['toolchain']:
+        suite = doctest.DocTestSuite(module)
+        suite.run(result)
+
+    # TODO: Surely we can just 'print' result?
+    print result
+    for test, err in result.errors:
+        print err
+    for test, err in result.failures:
+        print err
 
     sys.argv = [sys.argv[0]]
     suite = unittest.TestLoader().loadTestsFromTestCase(test.TestBuild)
index bcdedfbf3f603744b139cf6a487e12d03801d406..068784a3041c03bac6370eb5621a3d8587389872 100644 (file)
@@ -60,11 +60,11 @@ commits = [
 ]
 
 boards = [
-    ['board0', 'arm', 'armv7', 'ARM Board 1', 'Tester', '', ''],
-    ['board1', 'arm', 'armv7', 'ARM Board 2', 'Tester', '', ''],
-    ['board2', 'powerpc', 'powerpc', 'PowerPC board 1', 'Tester', '', ''],
-    ['board3', 'powerpc', 'mpc5xx', 'PowerPC board 2', 'Tester', '', ''],
-    ['board4', 'sandbox', 'sandbox', 'Sandbox board', 'Tester', '', '']
+    ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 1', 'board0',  ''],
+    ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 2', 'board1', ''],
+    ['Active', 'powerpc', 'powerpc', '', 'Tester', 'PowerPC board 1', 'board2', ''],
+    ['Active', 'powerpc', 'mpc5xx', '', 'Tester', 'PowerPC board 2', 'board3', ''],
+    ['Active', 'sandbox', 'sandbox', '', 'Tester', 'Sandbox board', 'board4', ''],
 ]
 
 class Options:
index dfa1d00ce27a3d58dcb9eb2bce1d7c666e01c740..a292338b6d0894bd4cd5ca78154bd3c4c9b77b66 100644 (file)
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+import re
 import glob
 import os
 
@@ -97,12 +98,18 @@ class Toolchains:
     def __init__(self):
         self.toolchains = {}
         self.paths = []
-        for name, value in bsettings.GetItems('toolchain'):
+        toolchains = bsettings.GetItems('toolchain')
+        if not toolchains:
+            print ("Warning: No tool chains - please add a [toolchain] section"
+                 " to your buildman config file %s. See README for details" %
+                 config_fname)
+
+        for name, value in toolchains:
             if '*' in value:
                 self.paths += glob.glob(value)
             else:
                 self.paths.append(value)
-
+        self._make_flags = dict(bsettings.GetItems('make-flags'))
 
     def Add(self, fname, test=True, verbose=False):
         """Add a toolchain to our list
@@ -167,3 +174,73 @@ class Toolchains:
         if not arch in self.toolchains:
             raise ValueError, ("No tool chain found for arch '%s'" % arch)
         return self.toolchains[arch]
+
+    def ResolveReferences(self, var_dict, args):
+        """Resolve variable references in a string
+
+        This converts ${blah} within the string to the value of blah.
+        This function works recursively.
+
+        Args:
+            var_dict: Dictionary containing variables and their values
+            args: String containing make arguments
+        Returns:
+            Resolved string
+
+        >>> bsettings.Setup()
+        >>> tcs = Toolchains()
+        >>> tcs.Add('fred', False)
+        >>> var_dict = {'oblique' : 'OBLIQUE', 'first' : 'fi${second}rst', \
+                        'second' : '2nd'}
+        >>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set')
+        'this=OBLIQUE_set'
+        >>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set${first}nd')
+        'this=OBLIQUE_setfi2ndrstnd'
+        """
+        re_var = re.compile('(\$\{[a-z0-9A-Z]{1,}\})')
+
+        while True:
+            m = re_var.search(args)
+            if not m:
+                break
+            lookup = m.group(0)[2:-1]
+            value = var_dict.get(lookup, '')
+            args = args[:m.start(0)] + value + args[m.end(0):]
+        return args
+
+    def GetMakeArguments(self, board):
+        """Returns 'make' arguments for a given board
+
+        The flags are in a section called 'make-flags'. Flags are named
+        after the target they represent, for example snapper9260=TESTING=1
+        will pass TESTING=1 to make when building the snapper9260 board.
+
+        References to other boards can be added in the string also. For
+        example:
+
+        [make-flags]
+        at91-boards=ENABLE_AT91_TEST=1
+        snapper9260=${at91-boards} BUILD_TAG=442
+        snapper9g45=${at91-boards} BUILD_TAG=443
+
+        This will return 'ENABLE_AT91_TEST=1 BUILD_TAG=442' for snapper9260
+        and 'ENABLE_AT91_TEST=1 BUILD_TAG=443' for snapper9g45.
+
+        A special 'target' variable is set to the board target.
+
+        Args:
+            board: Board object for the board to check.
+        Returns:
+            'make' flags for that board, or '' if none
+        """
+        self._make_flags['target'] = board.target
+        arg_str = self.ResolveReferences(self._make_flags,
+                           self._make_flags.get(board.target, ''))
+        args = arg_str.split(' ')
+        i = 0
+        while i < len(args):
+            if not args[i]:
+                del args[i]
+            else:
+                i += 1
+        return args
index 896e2bc985f4a24a00f5d27d1a9bb0dc230258cf..88c5bc77354644cd875ba9a2108b0cc7582820c1 100755 (executable)
@@ -398,7 +398,7 @@ sub top_of_kernel_tree {
        my ($root) = @_;
 
        my @tree_check = (
-               "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
+               "COPYING", "CREDITS", "Kbuild", "Makefile",
                "README", "Documentation", "arch", "include", "drivers",
                "fs", "init", "ipc", "kernel", "lib", "scripts",
        );
@@ -3701,7 +3701,7 @@ sub process {
 $vname has style problems, please review.
 
 If any of these errors are false positives, please report
-them to the maintainer, see CHECKPATCH in MAINTAINERS.
+them to the maintainer, see boards.cfg.
 EOM
        }
 
index 47beaaff2a2836850746ebee3d27707b4aad24a1..0400a606785457c8711eaa2bf85b51768aa180f6 100644 (file)
@@ -23,7 +23,7 @@ static image_header_t header;
 static int fit_verify_header (unsigned char *ptr, int image_size,
                        struct mkimage_params *params)
 {
-       return fdt_check_header ((void *)ptr);
+       return fdt_check_header(ptr);
 }
 
 static int fit_check_image_types (uint8_t type)