]> 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>
Fri, 4 Oct 2013 17:17:48 +0000 (13:17 -0400)
committerTom Rini <trini@ti.com>
Fri, 4 Oct 2013 17:17:48 +0000 (13:17 -0400)
123 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/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-omap5/ehci.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/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/w7o/init.S
boards.cfg
common/cmd_bootm.c
common/cmd_dfu.c
common/cmd_gpt.c
common/cmd_mmc.c
common/cmd_mtdparts.c
common/cmd_pxe.c
common/cmd_sf.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.hwconfig
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/net/4xx_enet.c
drivers/net/npe/miiphy.c
drivers/net/phy/smsc.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/mxs_spi.c
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
examples/standalone/README.smc91111_eeprom
include/common.h
include/configs/P2041RDB.h
include/configs/am335x_evm.h
include/configs/eXalion.h
include/configs/sacsng.h
include/configs/sama5d3xek.h
include/dfu.h
include/i2s.h
include/libfdt.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/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 1365db68febb159191da179333c81938671d4105..b09bfcca8d89d91aedfd02ca17a19b30bc548e55 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.
@@ -838,7 +838,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 2fcad7ff856f408cc9e0122b4751cb41fb118794..b99a4441582f21d14660e107e6106600265e6d80 100644 (file)
--- a/README
+++ b/README
@@ -152,9 +152,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
@@ -178,6 +175,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
@@ -200,12 +200,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
@@ -215,7 +219,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:
@@ -1404,6 +1408,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
@@ -3359,7 +3369,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
@@ -3472,7 +3482,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 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 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 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 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 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 80846c966cda9b03d19ad26c01bb91e48f7c0ae1..c90ddddf1352b333c82ef70dc6b1f1c0c12fcded 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 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..38a6e6d07e443ab3ff450c73a036fe0b21f68df6 100644 (file)
@@ -420,7 +420,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
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 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 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 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 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 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 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;
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 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
index 4d2a56d0dea327cffd5f805d84132a655a7c760d..f1a590a15ef2fd1ec8aadb8ec95d8c0fe7feaee6 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
  */
@@ -1017,10 +1017,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 cdf689f875a81bd1030319044b794efd4ccfe265..348247050a98213c10bcb768ae5ad7be11afd595 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} " \
        "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 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 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 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 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 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.
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 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)