summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Licenses/README2
-rw-r--r--Makefile10
-rw-r--r--README22
-rw-r--r--arch/arm/cpu/arm926ejs/at91/eflash.c2
-rw-r--r--arch/arm/cpu/arm926ejs/kirkwood/cpu.c2
-rw-r--r--arch/arm/cpu/armv7/at91/sama5d3_devices.c12
-rw-r--r--arch/arm/cpu/armv7/exynos/clock.c61
-rw-r--r--arch/arm/cpu/armv7/exynos/pinmux.c23
-rw-r--r--arch/arm/dts/exynos5250.dtsi19
-rw-r--r--arch/arm/include/asm/arch-at91/at91_common.h1
-rw-r--r--arch/arm/include/asm/arch-at91/atmel_usba_udc.h64
-rw-r--r--arch/arm/include/asm/arch-at91/sama5d3.h2
-rw-r--r--arch/arm/include/asm/arch-exynos/clk.h5
-rw-r--r--arch/arm/include/asm/arch-exynos/clock.h4
-rw-r--r--arch/arm/include/asm/arch-exynos/cpu.h4
-rw-r--r--arch/arm/include/asm/arch-exynos/i2s-regs.h6
-rw-r--r--arch/arm/include/asm/arch-exynos/periph.h1
-rw-r--r--arch/arm/include/asm/arch-omap5/ehci.h15
-rw-r--r--arch/powerpc/cpu/mpc85xx/cmd_errata.c3
-rw-r--r--arch/powerpc/cpu/mpc85xx/start.S8
-rw-r--r--arch/powerpc/cpu/ppc4xx/4xx_pci.c2
-rw-r--r--arch/powerpc/cpu/ppc4xx/4xx_uart.c2
-rw-r--r--arch/powerpc/cpu/ppc4xx/miiphy.c2
-rw-r--r--arch/powerpc/cpu/ppc4xx/start.S2
-rw-r--r--arch/powerpc/include/asm/config_mpc85xx.h21
-rw-r--r--arch/powerpc/include/asm/ppc405.h2
-rw-r--r--arch/powerpc/include/asm/ppc440.h2
-rw-r--r--arch/powerpc/include/asm/ppc4xx-emac.h2
-rw-r--r--arch/powerpc/include/asm/ppc4xx-mal.h2
-rw-r--r--arch/powerpc/include/asm/ppc4xx.h2
-rw-r--r--board/RPXlite_dw/README4
-rw-r--r--board/atmel/sama5d3xek/sama5d3xek.c13
-rw-r--r--board/cray/L1/init.S2
-rw-r--r--board/csb272/init.S2
-rw-r--r--board/csb472/init.S2
-rw-r--r--board/esd/pci405/writeibm.S2
-rw-r--r--board/freescale/mx28evk/README4
-rw-r--r--board/jse/init.S2
-rw-r--r--board/mpl/common/pci.c2
-rw-r--r--board/mpl/mip405/init.S2
-rw-r--r--board/mpl/pip405/init.S2
-rw-r--r--board/samsung/dts/exynos5250-smdk5250.dts13
-rw-r--r--board/samsung/dts/exynos5250-snow.dts14
-rw-r--r--board/sbc8349/README2
-rw-r--r--board/sc3/init.S2
-rw-r--r--board/w7o/init.S2
-rw-r--r--boards.cfg2
-rw-r--r--common/cmd_bootm.c9
-rw-r--r--common/cmd_dfu.c19
-rw-r--r--common/cmd_gpt.c4
-rw-r--r--common/cmd_mmc.c4
-rw-r--r--common/cmd_mtdparts.c2
-rw-r--r--common/cmd_pxe.c20
-rw-r--r--common/cmd_sf.c13
-rw-r--r--common/cmd_usb_mass_storage.c1
-rw-r--r--common/image-fdt.c2
-rw-r--r--common/image-fit.c8
-rw-r--r--common/image.c8
-rw-r--r--common/spl/spl_mmc.c17
-rw-r--r--disk/part_efi.c3
-rw-r--r--doc/README.hwconfig2
-rw-r--r--doc/git-mailrc2
-rw-r--r--doc/uImage.FIT/command_syntax_extensions.txt2
-rw-r--r--doc/uImage.FIT/source_file_format.txt2
-rw-r--r--drivers/block/sym53c8xx.c2
-rw-r--r--drivers/dfu/Makefile1
-rw-r--r--drivers/dfu/dfu.c34
-rw-r--r--drivers/dfu/dfu_mmc.c9
-rw-r--r--drivers/dfu/dfu_nand.c7
-rw-r--r--drivers/dfu/dfu_ram.c77
-rw-r--r--drivers/mmc/Makefile2
-rw-r--r--drivers/mmc/dw_mmc.c9
-rw-r--r--drivers/mmc/mmc.c205
-rw-r--r--drivers/mmc/mmc_private.h45
-rw-r--r--drivers/mmc/mmc_write.c179
-rw-r--r--drivers/mmc/omap_hsmmc.c41
-rw-r--r--drivers/mmc/s5p_sdhci.c4
-rw-r--r--drivers/mmc/sdhci.c18
-rw-r--r--drivers/net/4xx_enet.c2
-rw-r--r--drivers/net/npe/miiphy.c2
-rw-r--r--drivers/net/phy/smsc.c2
-rw-r--r--drivers/sound/max98095.c155
-rw-r--r--drivers/sound/max98095.h10
-rw-r--r--drivers/sound/samsung-i2s.c65
-rw-r--r--drivers/sound/sound.c28
-rw-r--r--drivers/sound/wm8994.c167
-rw-r--r--drivers/sound/wm8994_registers.h39
-rw-r--r--drivers/spi/mxs_spi.c12
-rw-r--r--drivers/usb/gadget/Makefile2
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c1306
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.h326
-rw-r--r--drivers/usb/gadget/config.c6
-rw-r--r--drivers/usb/gadget/ether.c5
-rw-r--r--drivers/usb/gadget/f_dfu.h3
-rw-r--r--drivers/usb/gadget/g_dnl.c5
-rw-r--r--drivers/usb/host/ehci-hcd.c38
-rw-r--r--examples/standalone/README.smc91111_eeprom6
-rw-r--r--include/common.h6
-rw-r--r--include/configs/P2041RDB.h4
-rw-r--r--include/configs/am335x_evm.h6
-rw-r--r--include/configs/eXalion.h2
-rw-r--r--include/configs/sacsng.h2
-rw-r--r--include/configs/sama5d3xek.h8
-rw-r--r--include/dfu.h35
-rw-r--r--include/i2s.h1
-rw-r--r--include/libfdt.h4
-rw-r--r--include/linux/usb/atmel_usba_udc.h26
-rw-r--r--include/linux/usb/gadget.h1
-rw-r--r--include/miiphy.h2
-rw-r--r--include/mmc.h4
-rw-r--r--include/sdhci.h3
-rw-r--r--include/usb_mass_storage.h9
-rw-r--r--lib/hashtable.c2
-rw-r--r--post/board/lwmon5/sysmon.c2
-rw-r--r--tools/buildman/README22
-rw-r--r--tools/buildman/board.py13
-rw-r--r--tools/buildman/bsettings.py3
-rw-r--r--tools/buildman/builder.py1
-rwxr-xr-xtools/buildman/buildman.py13
-rw-r--r--tools/buildman/test.py10
-rw-r--r--tools/buildman/toolchain.py81
-rwxr-xr-xtools/checkpatch.pl4
-rw-r--r--tools/fit_image.c2
123 files changed, 3023 insertions, 550 deletions
diff --git a/Licenses/README b/Licenses/README
index 41961256a6..9f61192557 100644
--- a/Licenses/README
+++ b/Licenses/README
@@ -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
diff --git a/Makefile b/Makefile
index 1365db68fe..07abef4423 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
VERSION = 2013
PATCHLEVEL = 10
SUBLEVEL =
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
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 2fcad7ff85..b99a444158 100644
--- 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.
diff --git a/arch/arm/cpu/arm926ejs/at91/eflash.c b/arch/arm/cpu/arm926ejs/at91/eflash.c
index 3e21cdb2fd..3f39264289 100644
--- a/arch/arm/cpu/arm926ejs/at91/eflash.c
+++ b/arch/arm/cpu/arm926ejs/at91/eflash.c
@@ -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!
*/
diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
index cde3172fe3..d4711c070c 100644
--- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
+++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
@@ -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);
diff --git a/arch/arm/cpu/armv7/at91/sama5d3_devices.c b/arch/arm/cpu/armv7/at91/sama5d3_devices.c
index e55e1c6602..51f0a6dff1 100644
--- a/arch/arm/cpu/armv7/at91/sama5d3_devices.c
+++ b/arch/arm/cpu/armv7/at91/sama5d3_devices.c
@@ -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
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 0cb1a61aa1..36fedd630c 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -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)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index 1b05ebfd7a..8002bce79c 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -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;
}
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
index 4fff5e3694..1c5474f40b 100644
--- a/arch/arm/dts/exynos5250.dtsi
+++ b/arch/arm/dts/exynos5250.dtsi
@@ -93,9 +93,28 @@
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 {
diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h
index 9f54fddce5..abcb97d107 100644
--- a/arch/arm/include/asm/arch-at91/at91_common.h
+++ b/arch/arm/include/asm/arch-at91/at91_common.h
@@ -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
index 0000000000..6f540d23af
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/atmel_usba_udc.h
@@ -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
diff --git a/arch/arm/include/asm/arch-at91/sama5d3.h b/arch/arm/include/asm/arch-at91/sama5d3.h
index fefee5ed25..123a627cca 100644
--- a/arch/arm/include/asm/arch-at91/sama5d3.h
+++ b/arch/arm/include/asm/arch-at91/sama5d3.h
@@ -120,7 +120,7 @@
#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
diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
index 71075bd533..1d6fa9370f 100644
--- a/arch/arm/include/asm/arch-exynos/clk.h
+++ b/arch/arm/include/asm/arch-exynos/clk.h
@@ -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);
diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h
index 2b97b9a042..cf26eeffcf 100644
--- a/arch/arm/include/asm/arch-exynos/clock.h
+++ b/arch/arm/include/asm/arch-exynos/clock.h
@@ -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
diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
index cb924fba8b..4b67191c07 100644
--- a/arch/arm/include/asm/arch-exynos/cpu.h
+++ b/arch/arm/include/asm/arch-exynos/cpu.h
@@ -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
@@ -85,10 +86,12 @@
#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 */
diff --git a/arch/arm/include/asm/arch-exynos/i2s-regs.h b/arch/arm/include/asm/arch-exynos/i2s-regs.h
index 613b9b7a37..4a4a7a00b7 100644
--- a/arch/arm/include/asm/arch-exynos/i2s-regs.h
+++ b/arch/arm/include/asm/arch-exynos/i2s-regs.h
@@ -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__ */
diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h
index 9952155986..64bd8b7c91 100644
--- a/arch/arm/include/asm/arch-exynos/periph.h
+++ b/arch/arm/include/asm/arch-exynos/periph.h
@@ -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
diff --git a/arch/arm/include/asm/arch-omap5/ehci.h b/arch/arm/include/asm/arch-omap5/ehci.h
index 3921e4ab40..63aaa020d2 100644
--- a/arch/arm/include/asm/arch-omap5/ehci.h
+++ b/arch/arm/include/asm/arch-omap5/ehci.h
@@ -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
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index eea264b151..c441bd2f54 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -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))
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index ad57a9cfa7..be4f4ae870 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -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.
diff --git a/arch/powerpc/cpu/ppc4xx/4xx_pci.c b/arch/powerpc/cpu/ppc4xx/4xx_pci.c
index 5584e0f3e8..08781a1fb9 100644
--- a/arch/powerpc/cpu/ppc4xx/4xx_pci.c
+++ b/arch/powerpc/cpu/ppc4xx/4xx_pci.c
@@ -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
*
diff --git a/arch/powerpc/cpu/ppc4xx/4xx_uart.c b/arch/powerpc/cpu/ppc4xx/4xx_uart.c
index 50c28a0d39..c02058f79b 100644
--- a/arch/powerpc/cpu/ppc4xx/4xx_uart.c
+++ b/arch/powerpc/cpu/ppc4xx/4xx_uart.c
@@ -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>
diff --git a/arch/powerpc/cpu/ppc4xx/miiphy.c b/arch/powerpc/cpu/ppc4xx/miiphy.c
index e4a9db6767..10147de089 100644
--- a/arch/powerpc/cpu/ppc4xx/miiphy.c
+++ b/arch/powerpc/cpu/ppc4xx/miiphy.c
@@ -1,5 +1,5 @@
/*
- * SPDX-License-Identifier: GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*-----------------------------------------------------------------------------+
|
diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S
index d9d8cbffaa..38bbc5a9bc 100644
--- a/arch/powerpc/cpu/ppc4xx/start.S
+++ b/arch/powerpc/cpu/ppc4xx/start.S
@@ -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
*/
/*
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index 15e44de41e..bec8966fde 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -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
@@ -108,6 +111,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
#elif defined(CONFIG_MPC8572)
#define CONFIG_MAX_CPUS 2
@@ -117,6 +121,7 @@
#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
@@ -135,6 +140,7 @@
#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
@@ -149,6 +155,7 @@
#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)
@@ -164,6 +171,7 @@
#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)
@@ -176,6 +184,7 @@
#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
@@ -205,6 +214,7 @@
#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
@@ -216,6 +226,7 @@
#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
@@ -230,6 +241,7 @@
#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
@@ -241,6 +253,7 @@
#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
@@ -254,6 +267,7 @@
#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
@@ -268,6 +282,7 @@
#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)
@@ -283,6 +298,7 @@
#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)
@@ -293,6 +309,7 @@
#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
@@ -307,6 +324,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
#elif defined(CONFIG_PPC_P2041) /* also supports P2040 */
#define CONFIG_SYS_FSL_QORIQ_CHASSIS1
@@ -506,6 +524,7 @@
#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
@@ -525,6 +544,7 @@
#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
@@ -658,6 +678,7 @@
#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
diff --git a/arch/powerpc/include/asm/ppc405.h b/arch/powerpc/include/asm/ppc405.h
index 8bb342b929..f2ed16a216 100644
--- a/arch/powerpc/include/asm/ppc405.h
+++ b/arch/powerpc/include/asm/ppc405.h
@@ -1,5 +1,5 @@
/*
- * SPDX-License-Identifier: GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
#ifndef __PPC405_H__
diff --git a/arch/powerpc/include/asm/ppc440.h b/arch/powerpc/include/asm/ppc440.h
index 0f5bc8d1c7..0cfa88bff5 100644
--- a/arch/powerpc/include/asm/ppc440.h
+++ b/arch/powerpc/include/asm/ppc440.h
@@ -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__
diff --git a/arch/powerpc/include/asm/ppc4xx-emac.h b/arch/powerpc/include/asm/ppc4xx-emac.h
index e6eb332220..76fa95ca37 100644
--- a/arch/powerpc/include/asm/ppc4xx-emac.h
+++ b/arch/powerpc/include/asm/ppc4xx-emac.h
@@ -1,5 +1,5 @@
/*
- * SPDX-License-Identifier: GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*----------------------------------------------------------------------------+
|
diff --git a/arch/powerpc/include/asm/ppc4xx-mal.h b/arch/powerpc/include/asm/ppc4xx-mal.h
index d15290dc1a..ef8b174461 100644
--- a/arch/powerpc/include/asm/ppc4xx-mal.h
+++ b/arch/powerpc/include/asm/ppc4xx-mal.h
@@ -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
*/
/*----------------------------------------------------------------------------+
|
diff --git a/arch/powerpc/include/asm/ppc4xx.h b/arch/powerpc/include/asm/ppc4xx.h
index 8d703c6634..e6a3bff079 100644
--- a/arch/powerpc/include/asm/ppc4xx.h
+++ b/arch/powerpc/include/asm/ppc4xx.h
@@ -1,5 +1,5 @@
/*
- * SPDX-License-Identifier: GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
#ifndef __PPC4XX_H__
diff --git a/board/RPXlite_dw/README b/board/RPXlite_dw/README
index 14296b2ab4..9e2d0f42a0 100644
--- a/board/RPXlite_dw/README
+++ b/board/RPXlite_dw/README
@@ -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 \
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c
index 97caf64d40..b0965ef211 100644
--- a/board/atmel/sama5d3xek/sama5d3xek.c
+++ b/board/atmel/sama5d3xek/sama5d3xek.c
@@ -21,6 +21,10 @@
#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
@@ -221,6 +228,12 @@ int board_eth_init(bd_t *bis)
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;
}
diff --git a/board/cray/L1/init.S b/board/cray/L1/init.S
index 82f21b08b2..44c688d1f0 100644
--- a/board/cray/L1/init.S
+++ b/board/cray/L1/init.S
@@ -1,5 +1,5 @@
/*
- * SPDX-License-Identifier: GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*----------------------------------------------------------------------------- */
diff --git a/board/csb272/init.S b/board/csb272/init.S
index b1283aa69a..5961978c86 100644
--- a/board/csb272/init.S
+++ b/board/csb272/init.S
@@ -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>
diff --git a/board/csb472/init.S b/board/csb472/init.S
index f5805b7988..1ebc9ead3a 100644
--- a/board/csb472/init.S
+++ b/board/csb472/init.S
@@ -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>
diff --git a/board/esd/pci405/writeibm.S b/board/esd/pci405/writeibm.S
index 38acca12bf..03eaf97b78 100644
--- a/board/esd/pci405/writeibm.S
+++ b/board/esd/pci405/writeibm.S
@@ -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 */
diff --git a/board/freescale/mx28evk/README b/board/freescale/mx28evk/README
index 524f3fc494..0389a1d86c 100644
--- a/board/freescale/mx28evk/README
+++ b/board/freescale/mx28evk/README
@@ -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.
diff --git a/board/jse/init.S b/board/jse/init.S
index 7b918b558d..4e449fef20 100644
--- a/board/jse/init.S
+++ b/board/jse/init.S
@@ -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 */
diff --git a/board/mpl/common/pci.c b/board/mpl/common/pci.c
index 6ab263a4d9..cd969cb518 100644
--- a/board/mpl/common/pci.c
+++ b/board/mpl/common/pci.c
@@ -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
diff --git a/board/mpl/mip405/init.S b/board/mpl/mip405/init.S
index bf886c05c0..642f17c35b 100644
--- a/board/mpl/mip405/init.S
+++ b/board/mpl/mip405/init.S
@@ -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
diff --git a/board/mpl/pip405/init.S b/board/mpl/pip405/init.S
index 9ed27990a1..95fed34fcc 100644
--- a/board/mpl/pip405/init.S
+++ b/board/mpl/pip405/init.S
@@ -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
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts
index 1e94c7f82c..b1bba9662e 100644
--- a/board/samsung/dts/exynos5250-smdk5250.dts
+++ b/board/samsung/dts/exynos5250-smdk5250.dts
@@ -36,6 +36,7 @@
mmc3 = "/mmc@12230000";
serial0 = "/serial@12C30000";
console = "/serial@12C30000";
+ i2s = "/sound@3830000";
};
sromc@12250000 {
@@ -49,16 +50,14 @@
};
};
- 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>;
diff --git a/board/samsung/dts/exynos5250-snow.dts b/board/samsung/dts/exynos5250-snow.dts
index 7832e4edda..9b7e57e43d 100644
--- a/board/samsung/dts/exynos5250-snow.dts
+++ b/board/samsung/dts/exynos5250-snow.dts
@@ -36,6 +36,7 @@
mmc3 = "/mmc@12230000";
serial0 = "/serial@12C30000";
console = "/serial@12C30000";
+ i2s = "/sound@3830000";
};
i2c4: i2c@12ca0000 {
@@ -65,16 +66,15 @@
};
};
- 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>;
diff --git a/board/sbc8349/README b/board/sbc8349/README
index 2c35919f28..e2d60cc530 100644
--- a/board/sbc8349/README
+++ b/board/sbc8349/README
@@ -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
diff --git a/board/sc3/init.S b/board/sc3/init.S
index 9921f8fc4f..46323d2688 100644
--- a/board/sc3/init.S
+++ b/board/sc3/init.S
@@ -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>
diff --git a/board/w7o/init.S b/board/w7o/init.S
index 490411e6ee..54eda3299f 100644
--- a/board/w7o/init.S
+++ b/board/w7o/init.S
@@ -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>
diff --git a/boards.cfg b/boards.cfg
index 80846c966c..c90ddddf13 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -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
###########################################################################################################
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index b07b0f48b2..166b901d76 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -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)
diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c
index 793c422123..7ce92cec87 100644
--- a/common/cmd_dfu.c
+++ b/common/cmd_dfu.c
@@ -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);
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
index 06767aa5e5..a46f5cc343 100644
--- a/common/cmd_gpt.c
+++ b/common/cmd_gpt.c
@@ -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"
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 1cdeb443fc..67a94a7468 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -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 */
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index 3023479d1d..38a6e6d07e 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -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
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index a2fb50ab9d..c5f4a221b8 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -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);
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 4af0f0af26..3f60979ae7 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -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;
}
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
index 33a4715005..ccf7195946 100644
--- a/common/cmd_usb_mass_storage.c
+++ b/common/cmd_usb_mass_storage.c
@@ -5,7 +5,6 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <errno.h>
#include <common.h>
#include <command.h>
#include <g_dnl.h>
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 2e22cca54e..6f9ce7d37c 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -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;
}
diff --git a/common/image-fit.c b/common/image-fit.c
index 199b4ed16a..cf4b67e3e8 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -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;
}
diff --git a/common/image.c b/common/image.c
index 2c88091e6d..b0ae58ff3e 100644
--- a/common/image.c
+++ b/common/image.c
@@ -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
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index f27b4c277b..fc2f2260f8 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -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();
}
diff --git a/disk/part_efi.c b/disk/part_efi.c
index b7524d68ba..9c33ae7a31 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -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;
}
diff --git a/doc/README.hwconfig b/doc/README.hwconfig
index cf549651c7..b6ddb438cf 100644
--- a/doc/README.hwconfig
+++ b/doc/README.hwconfig
@@ -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.
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 2cacaa0341..251586e052 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -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
diff --git a/doc/uImage.FIT/command_syntax_extensions.txt b/doc/uImage.FIT/command_syntax_extensions.txt
index 002818c226..6c99b1c159 100644
--- a/doc/uImage.FIT/command_syntax_extensions.txt
+++ b/doc/uImage.FIT/command_syntax_extensions.txt
@@ -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:
diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt
index 6d2070758d..160b2d05f8 100644
--- a/doc/uImage.FIT/source_file_format.txt
+++ b/doc/uImage.FIT/source_file_format.txt
@@ -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.
diff --git a/drivers/block/sym53c8xx.c b/drivers/block/sym53c8xx.c
index c538e370e1..6f1ac85723 100644
--- a/drivers/block/sym53c8xx.c
+++ b/drivers/block/sym53c8xx.c
@@ -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)
{
diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile
index fca370ae04..de9e44e1ef 100644
--- a/drivers/dfu/Makefile
+++ b/drivers/dfu/Makefile
@@ -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))
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index d73d510391..56b21c78ab 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -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];
}
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 0871a770b7..f942758696 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -13,16 +13,11 @@
#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];
diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c
index 0ec12cff26..edbf5a97b9 100644
--- a/drivers/dfu/dfu_nand.c
+++ b/drivers/dfu/dfu_nand.c
@@ -19,12 +19,7 @@
#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
index 0000000000..335a8e1f24
--- /dev/null
+++ b/drivers/dfu/dfu_ram.c
@@ -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;
+}
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index bedf833f70..06280d1fa6 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -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)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index a82ee17a25..9a803a02d4 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -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);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 55026759ed..84dae4d8bd 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -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
index 0000000000..16dcf9ff61
--- /dev/null
+++ b/drivers/mmc/mmc_private.h
@@ -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
index 0000000000..aa2fdefa75
--- /dev/null
+++ b/drivers/mmc/mmc_write.c
@@ -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;
+}
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 975b2c5ba4..d3a8b5303d 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -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;
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 7f89403b43..40ff8739bf 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -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);
}
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 42619916e5..dfb2eeeb4d 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -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;
}
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index c98867dc4a..381ec42864 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -1,5 +1,5 @@
/*
- * SPDX-License-Identifier: GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*-----------------------------------------------------------------------------+
*
diff --git a/drivers/net/npe/miiphy.c b/drivers/net/npe/miiphy.c
index 07fcb60e9d..002fb8113b 100644
--- a/drivers/net/npe/miiphy.c
+++ b/drivers/net/npe/miiphy.c
@@ -1,5 +1,5 @@
/*
- * SPDX-License-Identifier: GPL-2.0 ibm-pibs
+ * SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*-----------------------------------------------------------------------------+
|
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 5936f9bd7f..60ed92d203 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -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>
diff --git a/drivers/sound/max98095.c b/drivers/sound/max98095.c
index d69db58dcd..febf4195ba 100644
--- a/drivers/sound/max98095.c
+++ b/drivers/sound/max98095.c
@@ -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;
diff --git a/drivers/sound/max98095.h b/drivers/sound/max98095.h
index ae5eb14dbb..44b1e3a97b 100644
--- a/drivers/sound/max98095.h
+++ b/drivers/sound/max98095.h
@@ -11,6 +11,12 @@
#ifndef _MAX98095_H
#define _MAX98095_H
+/* Available audio interface ports in wm8994 codec */
+enum en_max_audio_interface {
+ AIF1 = 1,
+ AIF2,
+};
+
/*
* MAX98095 Registers Definition
*/
@@ -305,7 +311,7 @@
*
* @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
diff --git a/drivers/sound/samsung-i2s.c b/drivers/sound/samsung-i2s.c
index 49921e5526..47f155f85d 100644
--- a/drivers/sound/samsung-i2s.c
+++ b/drivers/sound/samsung-i2s.c
@@ -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);
diff --git a/drivers/sound/sound.c b/drivers/sound/sound.c
index 6fcc75da58..9b8ce5a9ef 100644
--- a/drivers/sound/sound.c
+++ b/drivers/sound/sound.c
@@ -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,
diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c
index 37e354c5c8..f8e9a6eadd 100644
--- a/drivers/sound/wm8994.c
+++ b/drivers/sound/wm8994.c
@@ -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__);
@@ -608,13 +613,46 @@ static int wm8994_init_volume_aif2_dac1(void)
}
/*
+ * 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
*
* @param wm8994 wm8994 information
*
* @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;
diff --git a/drivers/sound/wm8994_registers.h b/drivers/sound/wm8994_registers.h
index 1e987c2fd1..0aba2fdfd8 100644
--- a/drivers/sound/wm8994_registers.h
+++ b/drivers/sound/wm8994_registers.h
@@ -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
@@ -82,6 +85,20 @@
/* 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)
*/
@@ -91,6 +108,12 @@
/* 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
@@ -170,6 +193,9 @@
/*
* 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
@@ -254,6 +280,8 @@
/* 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
@@ -261,6 +289,8 @@
/* 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
@@ -285,11 +315,12 @@
* 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
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index 3cf7142f5a..2b9f395a97 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -56,8 +56,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
struct mxs_spi_slave *mxs_slave;
- struct mxs_ssp_regs *ssp_regs;
- int reg;
if (!spi_cs_is_valid(bus, cs)) {
printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs);
@@ -74,13 +72,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
mxs_slave->max_khz = max_hz / 1000;
mxs_slave->mode = mode;
mxs_slave->regs = mxs_ssp_regs_by_bus(bus);
- ssp_regs = mxs_slave->regs;
- reg = readl(&ssp_regs->hw_ssp_ctrl0);
- reg &= ~(MXS_SSP_CHIPSELECT_MASK);
- reg |= cs << MXS_SSP_CHIPSELECT_SHIFT;
-
- writel(reg, &ssp_regs->hw_ssp_ctrl0);
return &mxs_slave->slave;
err_init:
@@ -102,7 +94,9 @@ int spi_claim_bus(struct spi_slave *slave)
mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg);
- writel(SSP_CTRL0_BUS_WIDTH_ONE_BIT, &ssp_regs->hw_ssp_ctrl0);
+ writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) |
+ SSP_CTRL0_BUS_WIDTH_ONE_BIT,
+ &ssp_regs->hw_ssp_ctrl0);
reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS;
reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0;
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 4c2a39a216..1590c4a750 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -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
index 0000000000..c99208d102
--- /dev/null
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -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
index 0000000000..92e462db60
--- /dev/null
+++ b/drivers/usb/gadget/atmel_usba_udc.h
@@ -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 */
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index f563afe787..014a6791c1 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -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;
}
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 579893cbff..700d5fbfb2 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -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
diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h
index 34a4dde5aa..cc2c45567b 100644
--- a/drivers/usb/gadget/f_dfu.h
+++ b/drivers/usb/gadget/f_dfu.h
@@ -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_ */
diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c
index a3e05a872a..40868c034e 100644
--- a/drivers/usb/gadget/g_dnl.c
+++ b/drivers/usb/gadget/g_dnl.c
@@ -7,7 +7,6 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <errno.h>
#include <common.h>
#include <malloc.h>
@@ -15,11 +14,11 @@
#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:
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index fdad739724..3ae04c0253 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -36,6 +36,12 @@
#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);
}
diff --git a/examples/standalone/README.smc91111_eeprom b/examples/standalone/README.smc91111_eeprom
index 28e7e69788..a2d52e7770 100644
--- a/examples/standalone/README.smc91111_eeprom
+++ b/examples/standalone/README.smc91111_eeprom
@@ -154,10 +154,10 @@ The MAC address can be stored in four locations:
-Boot environmental variable in Flash <- can not change, without
re-flashing U-boot.
-U-Boot environental variable <- can not change, without
+U-Boot environmental variable <- can not change, without
resetting board/U-Boot
-LAN91C111 Registers <- volitle
-LAN91C111 EEPROM <- Non Volitle
+LAN91C111 Registers <- volatile
+LAN91C111 EEPROM <- Non-volatile
If you have not activated the network, and do not have a hardcoded
or pre-assigned MAC address in U-boot, the environmental variables
diff --git a/include/common.h b/include/common.h
index 8addf43343..0d40fab041 100644
--- a/include/common.h
+++ b/include/common.h
@@ -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
*/
@@ -1015,10 +1015,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)
diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h
index 905bacfa96..862614b5c2 100644
--- a/include/configs/P2041RDB.h
+++ b/include/configs/P2041RDB.h
@@ -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
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index cdf689f875..348247050a 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -100,6 +100,7 @@
"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} " \
@@ -327,6 +328,11 @@
"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.
diff --git a/include/configs/eXalion.h b/include/configs/eXalion.h
index c2d04a21c7..7321b60c2f 100644
--- a/include/configs/eXalion.h
+++ b/include/configs/eXalion.h
@@ -119,7 +119,7 @@
#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 */
diff --git a/include/configs/sacsng.h b/include/configs/sacsng.h
index d63d0c4f54..0feef1eabb 100644
--- a/include/configs/sacsng.h
+++ b/include/configs/sacsng.h
@@ -305,7 +305,7 @@
#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" \
diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h
index 76fa500edd..79c00684dd 100644
--- a/include/configs/sama5d3xek.h
+++ b/include/configs/sama5d3xek.h
@@ -162,6 +162,14 @@
#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
diff --git a/include/dfu.h b/include/dfu.h
index 47b90559d5..b2ecf1bebe 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -14,11 +14,13 @@
#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_ */
diff --git a/include/i2s.h b/include/i2s.h
index aee52e7f14..8dd2cc388a 100644
--- a/include/i2s.h
+++ b/include/i2s.h
@@ -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 */
};
/*
diff --git a/include/libfdt.h b/include/libfdt.h
index 765d84f5e4..9eefaaf5f8 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -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
index 0000000000..be29ef0c5c
--- /dev/null
+++ b/include/linux/usb/atmel_usba_udc.h
@@ -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 */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 220d068600..a8a576316d 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -18,6 +18,7 @@
#ifndef __LINUX_USB_GADGET_H
#define __LINUX_USB_GADGET_H
+#include <errno.h>
#include <linux/list.h>
struct usb_ep;
diff --git a/include/miiphy.h b/include/miiphy.h
index 657b49624a..088797e4c6 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -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.
*/
diff --git a/include/mmc.h b/include/mmc.h
index 228d77139d..214b9edc8d 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -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);
diff --git a/include/sdhci.h b/include/sdhci.h
index b18b87312b..74d06ae18a 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -192,6 +192,8 @@
#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.
*/
@@ -210,6 +212,7 @@
#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;
diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h
index 35cdcc3d8c..e08deb4ddf 100644
--- a/include/usb_mass_storage.h
+++ b/include/usb_mass_storage.h
@@ -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__ */
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 644330a17e..c5a2b08bec 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -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
diff --git a/post/board/lwmon5/sysmon.c b/post/board/lwmon5/sysmon.c
index da37d66bfa..cca1a26235 100644
--- a/post/board/lwmon5/sysmon.c
+++ b/post/board/lwmon5/sysmon.c
@@ -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
*/
diff --git a/tools/buildman/README b/tools/buildman/README
index 734ada65a8..f63f278673 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -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
=============
diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index a388896417..1d3db206bd 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -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)
diff --git a/tools/buildman/bsettings.py b/tools/buildman/bsettings.py
index c80113056c..916479866c 100644
--- a/tools/buildman/bsettings.py
+++ b/tools/buildman/bsettings.py
@@ -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
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 29da67a54e..4a2d753c21 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -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:
diff --git a/tools/buildman/buildman.py b/tools/buildman/buildman.py
index 6fba2f292a..43895b87ea 100755
--- a/tools/buildman/buildman.py
+++ b/tools/buildman/buildman.py
@@ -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)
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index bcdedfbf3f..068784a304 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -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:
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index dfa1d00ce2..a292338b6d 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -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
diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl
index 896e2bc985..88c5bc7735 100755
--- a/tools/checkpatch.pl
+++ b/tools/checkpatch.pl
@@ -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
}
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 47beaaff2a..0400a60678 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -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)