diff options
123 files changed, 3015 insertions, 542 deletions
| diff --git a/Licenses/README b/Licenses/README index 41961256a..9f6119255 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 @@ -8,7 +8,7 @@  VERSION = 2013  PATCHLEVEL = 10  SUBLEVEL = -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc4  ifneq "$(SUBLEVEL)" ""  U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)  else @@ -45,13 +45,13 @@ endif  #########################################################################  # -# U-boot build supports producing a object files to the separate external +# U-boot build supports generating object files in a separate external  # directory. Two use cases are supported:  #  # 1) Add O= to the make command line  # 'make O=/tmp/build all'  # -# 2) Set environement variable BUILD_DIR to point to the desired location +# 2) Set environment variable BUILD_DIR to point to the desired location  # 'export BUILD_DIR=/tmp/build'  # 'make'  # @@ -59,7 +59,7 @@ endif  # 'export BUILD_DIR=/tmp/build'  # './MAKEALL'  # -# Command line 'O=' setting overrides BUILD_DIR environent variable. +# Command line 'O=' setting overrides BUILD_DIR environment variable.  #  # When none of the above methods is used the local build is performed and  # the object files are placed in the source directory. @@ -838,7 +838,7 @@ unconfig:  sinclude $(obj).boards.depend  $(obj).boards.depend:	boards.cfg -	@awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE) -d" }' $< > $@ +	@awk '(NF && $$1 !~ /^#/) { print $$7 ": " $$7 "_config; $$(MAKE)" }' $< > $@  #  # Functions to generate common board directory names @@ -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 3e21cdb2f..3f3926428 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 cde3172fe..d4711c070 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 e55e1c660..51f0a6dff 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 0cb1a61aa..36fedd630 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(); +	unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass(); -	clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK, -			(CLK_SRC_SCLK_EPLL)); +	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 1b05ebfd7..8002bce79 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 4fff5e369..1c5474f40 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 9f54fddce..abcb97d10 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 000000000..6f540d23a --- /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 fefee5ed2..123a627cc 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 71075bd53..1d6fa9370 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 2b97b9a04..cf26eeffc 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 cb924fba8..4b67191c0 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 613b9b7a3..4a4a7a00b 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 995215598..64bd8b7c9 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 3921e4ab4..63aaa020d 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 eea264b15..c441bd2f5 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 ad57a9cfa..be4f4ae87 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 5584e0f3e..08781a1fb 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 50c28a0d3..c02058f79 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 e4a9db676..10147de08 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 d9d8cbffa..38bbc5a9b 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 15e44de41..bec8966fd 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 8bb342b92..f2ed16a21 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 0f5bc8d1c..0cfa88bff 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 e6eb33222..76fa95ca3 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 d15290dc1..ef8b17446 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 8d703c663..e6a3bff07 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 14296b2ab..9e2d0f42a 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 97caf64d4..b0965ef21 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 82f21b08b..44c688d1f 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 b1283aa69..5961978c8 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 f5805b798..1ebc9ead3 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 38acca12b..03eaf97b7 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 524f3fc49..0389a1d86 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 7b918b558..4e449fef2 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 6ab263a4d..cd969cb51 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 bf886c05c..642f17c35 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 9ed27990a..95fed34fc 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 1e94c7f82..b1bba9662 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 7832e4edd..9b7e57e43 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 2c35919f2..e2d60cc53 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 9921f8fc4..46323d268 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 490411e6e..54eda3299 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 80846c966..c90ddddf1 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 b07b0f48b..166b901d7 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 793c42212..7ce92cec8 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 06767aa5e..a46f5cc34 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 1cdeb443f..67a94a746 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 3023479d1..38a6e6d07 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 a2fb50ab9..c5f4a221b 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 4af0f0af2..3f60979ae 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 33a471500..ccf719594 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 2e22cca54..6f9ce7d37 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 199b4ed16..cf4b67e3e 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 2c88091e6..b0ae58ff3 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 f27b4c277..fc2f2260f 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 b7524d68b..9c33ae7a3 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 cf549651c..b6ddb438c 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 2cacaa034..251586e05 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 002818c22..6c99b1c15 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 6d2070758..160b2d05f 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 c538e370e..6f1ac8572 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 fca370ae0..de9e44e1e 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 d73d51039..56b21c78a 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 0871a770b..f94275869 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 0ec12cff2..edbf5a97b 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 000000000..335a8e1f2 --- /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 bedf833f7..06280d1fa 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 a82ee17a2..9a803a02d 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 55026759e..84dae4d8b 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 000000000..16dcf9ff6 --- /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 000000000..aa2fdefa7 --- /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 975b2c5ba..d3a8b5303 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 7f89403b4..40ff8739b 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 42619916e..dfb2eeeb4 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 c98867dc4..381ec4286 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 07fcb60e9..002fb8113 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 5936f9bd7..60ed92d20 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 d69db58dc..febf4195b 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, ®val)) {  		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 ae5eb14db..44b1e3a97 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 49921e552..47f155f85 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); -	/* Initialize GPIO for I2s */ -	exynos_pinmux_config(PERIPH_ID_I2S1, 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; +	} -	/* 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 6fcc75da5..9b8ce5a9e 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 37e354c5c..f8e9a6ead 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); +	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_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING, -			WM8994_AIF2DACR_TO_DAC1R_MASK, -			WM8994_AIF2DACR_TO_DAC1R); +		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); -	 /* 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); +		ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING, +				WM8994_AIF2DACR_TO_DAC1R_MASK, +				WM8994_AIF2DACR_TO_DAC1R); -	/* 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); +		/* 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); -	/* 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); +		/* 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(); +	} -	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 1e987c2fd..0aba2fdfd 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 3cf7142f5..2b9f395a9 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 4c2a39a21..1590c4a75 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 000000000..c99208d10 --- /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 000000000..92e462db6 --- /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 f563afe78..014a6791c 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 579893cbf..700d5fbfb 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 34a4dde5a..cc2c45567 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 a3e05a872..40868c034 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 fdad73972..3ae04c025 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 28e7e6978..a2d52e777 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 4d2a56d0d..f1a590a15 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   */ @@ -1017,10 +1017,10 @@ static inline phys_addr_t map_to_sysmem(void *ptr)   * of a function scoped static buffer.  It can not be used to create a cache   * line aligned global buffer.   */ -#define PAD_COUNT(s, pad) ((s - 1) / pad + 1) +#define PAD_COUNT(s, pad) (((s) - 1) / (pad) + 1)  #define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)  #define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad)		\ -	char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align)  \ +	char __##name[ROUND(PAD_SIZE((size) * sizeof(type), pad), align)  \  		      + (align - 1)];					\  									\  	type *name = (type *) ALIGN((uintptr_t)__##name, align) diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 905bacfa9..862614b5c 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 cdf689f87..348247050 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 c2d04a21c..7321b60c2 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 d63d0c4f5..0feef1eab 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 76fa500ed..79c00684d 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 47b90559d..b2ecf1beb 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 aee52e7f1..8dd2cc388 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 765d84f5e..9eefaaf5f 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 000000000..be29ef0c5 --- /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 220d06860..a8a576316 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 657b49624..088797e4c 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 228d77139..214b9edc8 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 b18b87312..74d06ae18 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 35cdcc3d8..e08deb4dd 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 644330a17..c5a2b08be 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 da37d66bf..cca1a2623 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 734ada65a..f63f27867 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 a38889641..1d3db206b 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 c80113056..916479866 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 29da67a54..4a2d753c2 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 6fba2f292..43895b87e 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 bcdedfbf3..068784a30 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 dfa1d00ce..a292338b6 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 896e2bc98..88c5bc773 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 47beaaff2..0400a6067 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) |