diff options
68 files changed, 1688 insertions, 485 deletions
| @@ -807,7 +807,6 @@ clean:  	       $(obj)board/matrix_vision/*/bootscript.img		  \  	       $(obj)board/voiceblue/eeprom 				  \  	       $(obj)u-boot.lds						  \ -	       $(obj)arch/blackfin/cpu/bootrom-asm-offsets.[chs]	  \  	       $(obj)arch/blackfin/cpu/init.{lds,elf}  	@rm -f $(obj)include/bmp_logo.h  	@rm -f $(obj)include/bmp_logo_data.h @@ -2141,6 +2141,12 @@ CBFS (Coreboot Filesystem) support  		  - set CONFIG_SYS_I2C_ZYNQ_SPEED for speed setting  		  - set CONFIG_SYS_I2C_ZYNQ_SLAVE for slave addr +		- drivers/i2c/s3c24x0_i2c.c: +		  - activate this driver with CONFIG_SYS_I2C_S3C24X0 +		  - This driver adds i2c buses (11 for Exynos5250, Exynos5420 +		    9 i2c buses for Exynos4 and 1 for S3C24X0 SoCs from Samsung) +		    with a fix speed from 100000 and the slave addr 0! +  		additional defines:  		CONFIG_SYS_NUM_I2C_BUSES diff --git a/arch/blackfin/cpu/.gitignore b/arch/blackfin/cpu/.gitignore index ba986d8ba..3df1fa21c 100644 --- a/arch/blackfin/cpu/.gitignore +++ b/arch/blackfin/cpu/.gitignore @@ -1,4 +1,2 @@ -bootrom-asm-offsets.[chs] -  init.lds  init.elf diff --git a/arch/blackfin/cpu/Makefile b/arch/blackfin/cpu/Makefile index 243dc22a0..a61594ab7 100644 --- a/arch/blackfin/cpu/Makefile +++ b/arch/blackfin/cpu/Makefile @@ -23,16 +23,6 @@ obj-y  += traps.o  extra-y += check_initcode -extra-y += bootrom-asm-offsets.h -$(obj)bootrom-asm-offsets.c: bootrom-asm-offsets.c.in bootrom-asm-offsets.awk -	echo '#include <asm/mach-common/bits/bootrom.h>' | $(CPP) $(CPPFLAGS) - | gawk -f ./bootrom-asm-offsets.awk > $@.tmp -	mv $@.tmp $@ -$(obj)bootrom-asm-offsets.s: $(obj)bootrom-asm-offsets.c -	$(CC) $(CFLAGS) -S $^ -o $@.tmp -	mv $@.tmp $@ -$(obj)bootrom-asm-offsets.h: $(obj)bootrom-asm-offsets.s -	sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}" $^ > $@ -  # make sure our initcode (which goes into LDR) does not  # have relocs or external references  $(obj)initcode.o: CFLAGS += -fno-function-sections -fno-data-sections diff --git a/arch/blackfin/cpu/bootrom-asm-offsets.awk b/arch/blackfin/cpu/bootrom-asm-offsets.awk deleted file mode 100644 index 1d6182425..000000000 --- a/arch/blackfin/cpu/bootrom-asm-offsets.awk +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/gawk -f -BEGIN { -	print "/* DO NOT EDIT: AUTOMATICALLY GENERATED" -	print " * Input files: bootrom-asm-offsets.awk bootrom-asm-offsets.c.in" -	print " * DO NOT EDIT: AUTOMATICALLY GENERATED" -	print " */" -	print "" -	system("cat bootrom-asm-offsets.c.in") -	print "{" -} - -{ -	/* find a structure definition */ -	if ($0 ~ /typedef struct .* {/) { -		delete members; -		i = 0; - -		/* extract each member of the structure */ -		while (1) { -			getline -			if ($1 == "}") -				break; -			gsub(/[*;]/, ""); -			members[i++] = $NF; -		} - -		/* grab the structure's name */ -		struct = $NF; -		sub(/;$/, "", struct); - -		/* output the DEFINE() macros */ -		while (i-- > 0) -			print "\tDEFINE(" struct ", " members[i] ");" -		print "" -	} -} - -END { -	print "\treturn 0;" -	print "}" -} diff --git a/arch/blackfin/cpu/bootrom-asm-offsets.c.in b/arch/blackfin/cpu/bootrom-asm-offsets.c.in deleted file mode 100644 index 64c2f2412..000000000 --- a/arch/blackfin/cpu/bootrom-asm-offsets.c.in +++ /dev/null @@ -1,12 +0,0 @@ -/* A little trick taken from the kernel asm-offsets.h where we convert - * the C structures automatically into a bunch of defines for use in - * the assembly files. - */ - -#include <linux/stddef.h> -#include <asm/mach-common/bits/bootrom.h> - -#define _DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val)) -#define DEFINE(s, m) _DEFINE(offset_##s##_##m, offsetof(s, m)) - -int main(int argc, char * const argv[]) diff --git a/arch/blackfin/cpu/gpio.c b/arch/blackfin/cpu/gpio.c index 5e9c68af8..86da706f0 100644 --- a/arch/blackfin/cpu/gpio.c +++ b/arch/blackfin/cpu/gpio.c @@ -12,7 +12,7 @@  #include <asm/gpio.h>  #include <asm/portmux.h> -#ifdef CONFIG_ADI_GPIO1 +#ifndef CONFIG_ADI_GPIO2  #if ANOMALY_05000311 || ANOMALY_05000323  enum {  	AWA_data = SYSCR, diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 376ec02b6..6ebcf01af 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -72,7 +72,7 @@  #ifndef __ASSEMBLY__ -#ifdef CONFIG_ADI_GPIO1 +#ifndef CONFIG_ADI_GPIO2  void set_gpio_dir(unsigned, unsigned short);  void set_gpio_inen(unsigned, unsigned short);  void set_gpio_polar(unsigned, unsigned short); diff --git a/arch/powerpc/cpu/mpc83xx/Makefile b/arch/powerpc/cpu/mpc83xx/Makefile index c345dd6ae..cf9116274 100644 --- a/arch/powerpc/cpu/mpc83xx/Makefile +++ b/arch/powerpc/cpu/mpc83xx/Makefile @@ -38,9 +38,7 @@ obj-$(CONFIG_OF_LIBFDT) += fdt.o  # Stub implementations of cache management functions for USB  obj-y += cache.o -ifdef CONFIG_SYS_FSL_DDR2 -obj-$(CONFIG_MPC8349) += $(SRCTREE)/drivers/ddr/fsl/mpc85xx_ddr_gen2.o -else +ifndef CONFIG_SYS_FSL_DDRC_GEN2  obj-y += spd_sdram.o  endif  obj-$(CONFIG_SYS_FSL_DDR2) += law.o diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index 1a58a194f..46ae80c4d 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -86,6 +86,14 @@ void get_sys_info(sys_info_t *sys_info)  	mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>  			FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT)  			& FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK; +	/* T4240/T4160 Rev2.0 MEM_PLL_RAT uses a value which is half of +	 * T4240/T4160 Rev1.0. eg. It's 12 in Rev1.0, however, for Rev2.0 +	 * it uses 6. +	 */ +#if defined(CONFIG_PPC_T4240) || defined(CONFIG_PPC_T4160) +	if (SVR_MAJ(get_svr()) >= 2) +		mem_pll_rat *= 2; +#endif  	if (mem_pll_rat > 2)  		sys_info->freq_ddrbus *= mem_pll_rat;  	else diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 6a81fa73e..db84d10c5 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -886,7 +886,11 @@ delete_ccsr_l2_tlb:  	erratum_set_dcsr 0xb0008 0x00900000  	erratum_set_dcsr 0xb0e40 0xe00a0000  	erratum_set_ccsr 0x18600 CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY +#ifdef  CONFIG_RAMBOOT_PBL +	erratum_set_ccsr 0x10f00 0x495e5000 +#else  	erratum_set_ccsr 0x10f00 0x415e5000 +#endif  	erratum_set_ccsr 0x11f00 0x415e5000  	/* Make temp mapping uncacheable again, if it was initially */ diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index db66fd31f..26f44cb59 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -161,7 +161,7 @@ static struct option *long_opts;  int os_parse_args(struct sandbox_state *state, int argc, char *argv[])  { -	struct sb_cmdline_option **sb_opt = __u_boot_sandbox_option_start; +	struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start;  	size_t num_options = __u_boot_sandbox_option_count();  	size_t i; diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index f1cb7930b..1b1545478 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -13,7 +13,7 @@  int sandbox_early_getopt_check(void)  {  	struct sandbox_state *state = state_get_current(); -	struct sb_cmdline_option **sb_opt = __u_boot_sandbox_option_start; +	struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start;  	size_t num_options = __u_boot_sandbox_option_count();  	size_t i;  	int max_arg_len, max_noarg_len; @@ -40,7 +40,7 @@ int sandbox_early_getopt_check(void)  	max_noarg_len = max_arg_len + 7;  	for (i = 0; i < num_options; ++i) { -		struct sb_cmdline_option *opt = sb_opt[i]; +		struct sandbox_cmdline_option *opt = sb_opt[i];  		/* first output the short flag if it has one */  		if (opt->flag_short >= 0x100) @@ -61,12 +61,12 @@ int sandbox_early_getopt_check(void)  	os_exit(0);  } -static int sb_cmdline_cb_help(struct sandbox_state *state, const char *arg) +static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)  {  	/* just flag to sandbox_early_getopt_check to show usage */  	return 1;  } -SB_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help"); +SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");  int sandbox_main_loop_init(void)  { @@ -81,19 +81,20 @@ int sandbox_main_loop_init(void)  	return 0;  } -static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg) +static int sandbox_cmdline_cb_command(struct sandbox_state *state, +				      const char *arg)  {  	state->cmd = arg;  	return 0;  } -SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command"); +SANDBOX_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command"); -static int sb_cmdline_cb_fdt(struct sandbox_state *state, const char *arg) +static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)  {  	state->fdt_fname = arg;  	return 0;  } -SB_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT"); +SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");  int main(int argc, char *argv[])  { diff --git a/arch/sandbox/include/asm/config.h b/arch/sandbox/include/asm/config.h index 7755a4def..ec7729eb4 100644 --- a/arch/sandbox/include/asm/config.h +++ b/arch/sandbox/include/asm/config.h @@ -9,4 +9,12 @@  #define CONFIG_SANDBOX_ARCH +/* Used by drivers/spi/sandbox_spi.c and arch/sandbox/include/asm/state.h */ +#ifndef CONFIG_SANDBOX_SPI_MAX_BUS +#define CONFIG_SANDBOX_SPI_MAX_BUS 1 +#endif +#ifndef CONFIG_SANDBOX_SPI_MAX_CS +#define CONFIG_SANDBOX_SPI_MAX_CS 10 +#endif +  #endif diff --git a/arch/sandbox/include/asm/getopt.h b/arch/sandbox/include/asm/getopt.h index 685883cd3..3048c2cc3 100644 --- a/arch/sandbox/include/asm/getopt.h +++ b/arch/sandbox/include/asm/getopt.h @@ -18,7 +18,7 @@ struct sandbox_state;   * consumer code should focus on the macros below and   * the callback function.   */ -struct sb_cmdline_option { +struct sandbox_cmdline_option {  	/* The long flag name: "help" for "--help" */  	const char *flag;  	/* The (optional) short flag name: "h" for "-h" */ @@ -35,18 +35,19 @@ struct sb_cmdline_option {   * Internal macro to expand the lower macros into the necessary   * magic junk that makes this all work.   */ -#define _SB_CMDLINE_OPT(f, s, ha, h) \ -	static struct sb_cmdline_option sb_cmdline_option_##f = { \ +#define _SANDBOX_CMDLINE_OPT(f, s, ha, h) \ +	static struct sandbox_cmdline_option sandbox_cmdline_option_##f = { \  		.flag = #f, \  		.flag_short = s, \  		.help = h, \  		.has_arg = ha, \ -		.callback = sb_cmdline_cb_##f, \ +		.callback = sandbox_cmdline_cb_##f, \  	}; \  	/* Ppointer to the struct in a special section for the linker script */ \  	static __attribute__((section(".u_boot_sandbox_getopt"), used)) \ -		struct sb_cmdline_option *sb_cmdline_option_##f##_ptr = \ -		&sb_cmdline_option_##f +		struct sandbox_cmdline_option \ +			*sandbox_cmdline_option_##f##_ptr = \ +			&sandbox_cmdline_option_##f  /**   * Macros for end code to declare new command line flags. @@ -56,16 +57,16 @@ struct sb_cmdline_option {   * @param h   The help string displayed when showing --help   *   * This invocation: - *   SB_CMDLINE_OPT(foo, 0, "The foo arg"); + *   SANDBOX_CMDLINE_OPT(foo, 0, "The foo arg");   * Will create a new flag named "--foo" (no short option) that takes   * no argument.  If the user specifies "--foo", then the callback func - * sb_cmdline_cb_foo() will automatically be called. + * sandbox_cmdline_cb_foo() will automatically be called.   */ -#define SB_CMDLINE_OPT(f, ha, h) _SB_CMDLINE_OPT(f, 0, ha, h) +#define SANDBOX_CMDLINE_OPT(f, ha, h) _SANDBOX_CMDLINE_OPT(f, 0, ha, h)  /*   * Same as above, but @s is used to specify a short flag e.g. - *   SB_CMDLINE_OPT(foo, 'f', 0, "The foo arg"); + *   SANDBOX_CMDLINE_OPT(foo, 'f', 0, "The foo arg");   */ -#define SB_CMDLINE_OPT_SHORT(f, s, ha, h) _SB_CMDLINE_OPT(f, s, ha, h) +#define SANDBOX_CMDLINE_OPT_SHORT(f, s, ha, h) _SANDBOX_CMDLINE_OPT(f, s, ha, h)  #endif diff --git a/arch/sandbox/include/asm/sections.h b/arch/sandbox/include/asm/sections.h index 4c378600b..fbc1bd11a 100644 --- a/arch/sandbox/include/asm/sections.h +++ b/arch/sandbox/include/asm/sections.h @@ -11,9 +11,9 @@  #include <asm-generic/sections.h> -struct sb_cmdline_option; +struct sandbox_cmdline_option; -extern struct sb_cmdline_option *__u_boot_sandbox_option_start[], +extern struct sandbox_cmdline_option *__u_boot_sandbox_option_start[],  	*__u_boot_sandbox_option_end[];  static inline size_t __u_boot_sandbox_option_count(void) diff --git a/arch/sandbox/include/asm/spi.h b/arch/sandbox/include/asm/spi.h new file mode 100644 index 000000000..49b4a0f10 --- /dev/null +++ b/arch/sandbox/include/asm/spi.h @@ -0,0 +1,58 @@ +/* + * Simulate a SPI port and clients (see README.sandbox for details) + * + * Copyright (c) 2011-2013 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __ASM_SPI_H__ +#define __ASM_SPI_H__ + +#include <linux/types.h> + +/* + * The interface between the SPI bus and the SPI client.  The bus will + * instantiate a client, and that then call into it via these entry + * points.  These should be enough for the client to emulate the SPI + * device just like the real hardware. + */ +struct sandbox_spi_emu_ops { +	/* The bus wants to instantiate a new client, so setup everything */ +	int (*setup)(void **priv, const char *spec); +	/* The bus is done with us, so break things down */ +	void (*free)(void *priv); +	/* The CS has been "activated" -- we won't worry about low/high */ +	void (*cs_activate)(void *priv); +	/* The CS has been "deactivated" -- we won't worry about low/high */ +	void (*cs_deactivate)(void *priv); +	/* The client is rx-ing bytes from the bus, so it should tx some */ +	int (*xfer)(void *priv, const u8 *rx, u8 *tx, uint bytes); +}; + +/* + * There are times when the data lines are allowed to tristate.  What + * is actually sensed on the line depends on the hardware.  It could + * always be 0xFF/0x00 (if there are pull ups/downs), or things could + * float and so we'd get garbage back.  This func encapsulates that + * scenario so we can worry about the details here. + */ +static inline void sandbox_spi_tristate(u8 *buf, uint len) +{ +	/* XXX: make this into a user config option ? */ +	memset(buf, 0xff, len); +} + +/* + * Extract the bus/cs from the spi spec and return the start of the spi + * client spec.  If the bus/cs are invalid for the current config, then + * it returns NULL. + * + * Example: arg="0:1:foo" will set bus to 0, cs to 1, and return "foo" + */ +const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus, +				   unsigned long *cs); + +#endif diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 093c81d91..a38820bde 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -15,6 +15,11 @@ enum exit_type_id {  	STATE_EXIT_POWER_OFF,  }; +struct sandbox_spi_info { +	const char *spec; +	const struct sandbox_spi_emu_ops *ops; +}; +  /* The complete state of the test system */  struct sandbox_state {  	const char *cmd;		/* Command to execute */ @@ -23,6 +28,10 @@ struct sandbox_state {  	const char *parse_err;		/* Error to report from parsing */  	int argc;			/* Program arguments */  	char **argv; + +	/* Pointer to information for each SPI bus/cs */ +	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] +					[CONFIG_SANDBOX_SPI_MAX_CS];  };  /** diff --git a/board/freescale/c29xpcie/ddr.c b/board/freescale/c29xpcie/ddr.c index 968655c1b..7c915b036 100644 --- a/board/freescale/c29xpcie/ddr.c +++ b/board/freescale/c29xpcie/ddr.c @@ -5,6 +5,7 @@   */  #include <common.h> +#include <i2c.h>  #include <asm/fsl_law.h>  #include <fsl_ddr_sdram.h>  #include <fsl_ddr_dimm_params.h> @@ -92,3 +93,15 @@ void fsl_ddr_board_options(memctl_options_t *popts,  		popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;  	}  } + +void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) +{ +	int ret = i2c_read(i2c_address, 0, 2, (uint8_t *)spd, +				sizeof(generic_spd_eeprom_t)); + +	if (ret) { +		printf("DDR: failed to read SPD from address %u\n", +				i2c_address); +		memset(spd, 0, sizeof(generic_spd_eeprom_t)); +	} +} diff --git a/board/samsung/smdk5250/exynos5-dt.c b/board/samsung/smdk5250/exynos5-dt.c index 6bcc883b1..6aa050982 100644 --- a/board/samsung/smdk5250/exynos5-dt.c +++ b/board/samsung/smdk5250/exynos5-dt.c @@ -150,8 +150,6 @@ int power_init_board(void)  	set_ps_hold_ctrl(); -	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -  	if (pmic_init(I2C_PMIC))  		return -1; diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index 6bd106ed5..8aba51c00 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -57,15 +57,18 @@ int board_init(void)  void i2c_init_board(void)  { -	struct exynos4_gpio_part1 *gpio1 = -		(struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); +	int err;  	struct exynos4_gpio_part2 *gpio2 =  		(struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); -	/* I2C_5 -> PMIC -> Adapter 0 */ -	s5p_gpio_direction_output(&gpio1->b, 7, 1); -	s5p_gpio_direction_output(&gpio1->b, 6, 1); -	/* I2C_9 -> FG -> Adapter 1 */ +	/* I2C_5 -> PMIC */ +	err = exynos_pinmux_config(PERIPH_ID_I2C5, PINMUX_FLAG_NONE); +	if (err) { +		debug("I2C%d not configured\n", (I2C_5)); +		return; +	} + +	/* I2C_8 -> FG */  	s5p_gpio_direction_output(&gpio2->y4, 0, 1);  	s5p_gpio_direction_output(&gpio2->y4, 1, 1);  } @@ -290,10 +293,10 @@ int power_init_board(void)  	 * The FUEL_GAUGE is marked as I2C9 on the schematic, but connected  	 * to logical I2C adapter 1  	 */ -	ret = pmic_init(I2C_0); +	ret = pmic_init(I2C_5);  	ret |= pmic_init_max8997(); -	ret |= power_fg_init(I2C_1); -	ret |= power_muic_init(I2C_0); +	ret |= power_fg_init(I2C_8); +	ret |= power_muic_init(I2C_5);  	ret |= power_bat_init(0);  	if (ret)  		return ret; diff --git a/board/samsung/trats2/trats2.c b/board/samsung/trats2/trats2.c index 955252200..147de179c 100644 --- a/board/samsung/trats2/trats2.c +++ b/board/samsung/trats2/trats2.c @@ -118,12 +118,17 @@ static void board_external_gpio_init(void)  #ifdef CONFIG_SYS_I2C_INIT_BOARD  static void board_init_i2c(void)  { +	int err; +  	gpio1 = (struct exynos4x12_gpio_part1 *)samsung_get_base_gpio_part1();  	gpio2 = (struct exynos4x12_gpio_part2 *)samsung_get_base_gpio_part2();  	/* I2C_7 */ -	s5p_gpio_direction_output(&gpio1->d0, 2, 1); -	s5p_gpio_direction_output(&gpio1->d0, 3, 1); +	err = exynos_pinmux_config(PERIPH_ID_I2C7, PINMUX_FLAG_NONE); +	if (err) { +		debug("I2C%d not configured\n", (I2C_7)); +		return; +	}  	/* I2C_8 */  	s5p_gpio_direction_output(&gpio1->f1, 4, 1); @@ -135,6 +140,24 @@ static void board_init_i2c(void)  }  #endif +#ifdef CONFIG_SYS_I2C_SOFT +int get_soft_i2c_scl_pin(void) +{ +	if (I2C_ADAP_HWNR) +		return exynos4x12_gpio_part2_get_nr(m2, 1); /* I2C9 */ +	else +		return exynos4x12_gpio_part1_get_nr(f1, 4); /* I2C8 */ +} + +int get_soft_i2c_sda_pin(void) +{ +	if (I2C_ADAP_HWNR) +		return exynos4x12_gpio_part2_get_nr(m2, 0); /* I2C9 */ +	else +		return exynos4x12_gpio_part1_get_nr(f1, 5); /* I2C8 */ +} +#endif +  int board_early_init_f(void)  {  	check_hw_revision(); @@ -170,11 +193,11 @@ int power_init_board(void)  #ifdef CONFIG_SYS_I2C_INIT_BOARD  	board_init_i2c();  #endif -	pmic_init(I2C_0);		/* I2C adapter 0 - bus name I2C_5 */ +	pmic_init(I2C_7);		/* I2C adapter 7 - bus name s3c24x0_7 */  	pmic_init_max77686(); -	pmic_init_max77693(I2C_2);	/* I2C adapter 2 - bus name I2C_10 */ -	power_muic_init(I2C_2);		/* I2C adapter 2 - bus name I2C_10 */ -	power_fg_init(I2C_1);		/* I2C adapter 1 - bus name I2C_9 */ +	pmic_init_max77693(I2C_9);	/* I2C adapter 9 - bus name soft1 */ +	power_muic_init(I2C_9);		/* I2C adapter 9 - bus name soft1 */ +	power_fg_init(I2C_8);		/* I2C adapter 8 - bus name soft0 */  	power_bat_init(0);  	p_chrg = pmic_get("MAX77693_PMIC"); diff --git a/board/sandbox/sandbox/README.sandbox b/board/sandbox/sandbox/README.sandbox index 30b05416a..69895574f 100644 --- a/board/sandbox/sandbox/README.sandbox +++ b/board/sandbox/sandbox/README.sandbox @@ -31,6 +31,60 @@ the console. It does not set the terminal into raw mode, so cursor keys and  history will not work yet. +SPI Emulation +------------- + +Sandbox supports SPI and SPI flash emulation. + +This is controlled by the spi_sf argument, the format of which is: + +   bus:cs:device:file + +   bus    - SPI bus number +   cs     - SPI chip select number +   device - SPI device emulation name +   file   - File on disk containing the data + +For example: + + dd if=/dev/zero of=spi.bin bs=1M count=4 + ./u-boot --spi_sf 0:0:M25P16:spi.bin + +With this setup you can issue SPI flash commands as normal: + +=>sf probe +SF: Detected M25P16 with page size 64 KiB, total 2 MiB +=>sf read 0 0 10000 +SF: 65536 bytes @ 0x0 Read: OK +=> + +Since this is a full SPI emulation (rather than just flash), you can +also use low-level SPI commands: + +=>sspi 0:0 32 9f +FF202015 + +This is issuing a READ_ID command and getting back 20 (ST Micro) part +0x2015 (the M25P16). + +Drivers are connected to a particular bus/cs using sandbox's state +structure (see the 'spi' member). A set of operations must be provided +for each driver. + + +Configuration settings for the curious are: + +CONFIG_SANDBOX_SPI_MAX_BUS +	The maximum number of SPI buses supported by the driver (default 1). + +CONFIG_SANDBOX_SPI_MAX_CS +	The maximum number of chip selects supported by the driver +	(default 10). + +CONFIG_SPI_IDLE_VAL +	The idle value on the SPI bus + +  Tests  ----- diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index 02539c40a..39248054f 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -161,7 +161,7 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt  #if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)  		spi_read (addr, alen, buffer, len);  #else -		if (i2c_read (addr[0], addr[1], alen-1, buffer, len) != 0) +		if (i2c_read(addr[0], offset, alen - 1, buffer, len))  			rcode = 1;  #endif  		buffer += len; @@ -339,7 +339,7 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn  		/* Write is enabled ... now write eeprom value.  		 */  #endif -		if (i2c_write (addr[0], addr[1], alen-1, buffer, len) != 0) +		if (i2c_write(addr[0], offset, alen - 1, buffer, len))  			rcode = 1;  #endif diff --git a/doc/SPI/README.sandbox-spi b/doc/SPI/README.sandbox-spi new file mode 100644 index 000000000..bb73eaf28 --- /dev/null +++ b/doc/SPI/README.sandbox-spi @@ -0,0 +1,64 @@ +Sandbox SPI/SPI Flash Implementation +==================================== + +U-Boot supports SPI and SPI flash emuation in sandbox. This must be enabled +using the --spi_sf paramter when starting U-Boot. + +For example: + +$ make O=sandbox sandbox_config +$ make O=sandbox +$ ./sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin + +The four parameters to spi_sf are: + +   SPI bus number (typically 0) +   SPI chip select number (typically 0) +   SPI chip to emulate +   File containing emulated data + +Supported chips are W25Q16 (2MB), W25Q32 (4MB) and W25Q128 (16MB). Once +U-Boot it started you can use 'sf' commands as normal. For example: + +$ ./b/sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin \ +	-c "sf probe; sf test 0 100000; sf read 0 1000 1000; \ +		sf erase 1000 1000; sf write 0 1000 1000" + + +U-Boot 2013.10-00237-gd4e0fdb (Nov 07 2013 - 20:08:15) + +DRAM:  128 MiB +Using default environment + +In:    serial +Out:   serial +Err:   serial +SF: Detected W25Q128BV with page size 256 Bytes, erase size 4 KiB, total 16 MiB +SPI flash test: +0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps +1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps +2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps +3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps +Test passed +0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps +1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps +2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps +3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps +SF: 4096 bytes @ 0x1000 Read: OK +SF: 4096 bytes @ 0x1000 Erased: OK +SF: 4096 bytes @ 0x1000 Written: OK + + +Since the SPI bus is fully implemented as well as the SPI flash connected to +it, you can also use low-level SPI commands to access the flash. For example +this reads the device ID from the emulated chip: + +=> sspi 0 32 9f +FFEF4018 + + +Simon Glass +sjg@chromium.org +7/11/2013 +Note that the sandbox SPI implementation was written by Mike Frysinger +<vapier@gentoo.org>. diff --git a/doc/device-tree-bindings/spi/spi-bus.txt b/doc/device-tree-bindings/spi/spi-bus.txt new file mode 100644 index 000000000..800dafe5b --- /dev/null +++ b/doc/device-tree-bindings/spi/spi-bus.txt @@ -0,0 +1,92 @@ +SPI (Serial Peripheral Interface) busses + +SPI busses can be described with a node for the SPI master device +and a set of child nodes for each SPI slave on the bus.  For this +discussion, it is assumed that the system's SPI controller is in +SPI master mode.  This binding does not describe SPI controllers +in slave mode. + +The SPI master node requires the following properties: +- #address-cells  - number of cells required to define a chip select +    		address on the SPI bus. +- #size-cells     - should be zero. +- compatible      - name of SPI bus controller following generic names +    		recommended practice. +- cs-gpios	  - (optional) gpios chip select. +No other properties are required in the SPI bus node.  It is assumed +that a driver for an SPI bus device will understand that it is an SPI bus. +However, the binding does not attempt to define the specific method for +assigning chip select numbers.  Since SPI chip select configuration is +flexible and non-standardized, it is left out of this binding with the +assumption that board specific platform code will be used to manage +chip selects.  Individual drivers can define additional properties to +support describing the chip select layout. + +Optional property: +- num-cs : total number of chipselects + +If cs-gpios is used the number of chip select will automatically increased +with max(cs-gpios > hw cs) + +So if for example the controller has 2 CS lines, and the cs-gpios +property looks like this: + +cs-gpios = <&gpio1 0 0> <0> <&gpio1 1 0> <&gpio1 2 0>; + +Then it should be configured so that num_chipselect = 4 with the +following mapping: + +cs0 : &gpio1 0 0 +cs1 : native +cs2 : &gpio1 1 0 +cs3 : &gpio1 2 0 + +SPI slave nodes must be children of the SPI master node and can +contain the following properties. +- reg             - (required) chip select address of device. +- compatible      - (required) name of SPI device following generic names +    		recommended practice +- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz +- spi-cpol        - (optional) Empty property indicating device requires +    		inverse clock polarity (CPOL) mode +- spi-cpha        - (optional) Empty property indicating device requires +    		shifted clock phase (CPHA) mode +- spi-cs-high     - (optional) Empty property indicating device requires +    		chip select active high +- spi-3wire       - (optional) Empty property indicating device requires +    		    3-wire mode. +- spi-tx-bus-width - (optional) The bus width(number of data wires) that +                      used for MOSI. Defaults to 1 if not present. +- spi-rx-bus-width - (optional) The bus width(number of data wires) that +                      used for MISO. Defaults to 1 if not present. + +Some SPI controllers and devices support Dual and Quad SPI transfer mode. +It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD). +Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is +only 1(SINGLE), 2(DUAL) and 4(QUAD). +Dual/Quad mode is not allowed when 3-wire mode is used. + +If a gpio chipselect is used for the SPI slave the gpio number will be passed +via the cs_gpio + +SPI example for an MPC5200 SPI bus: +	spi@f00 { +		#address-cells = <1>; +		#size-cells = <0>; +		compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; +		reg = <0xf00 0x20>; +		interrupts = <2 13 0 2 14 0>; +		interrupt-parent = <&mpc5200_pic>; + +		ethernet-switch@0 { +			compatible = "micrel,ks8995m"; +			spi-max-frequency = <1000000>; +			reg = <0>; +		}; + +		codec@1 { +			compatible = "ti,tlv320aic26"; +			spi-max-frequency = <100000>; +			reg = <1>; +		}; +	}; diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 553b519cc..fa3a87570 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o  obj-$(CONFIG_I2C_MV) += mv_i2c.o  obj-$(CONFIG_I2C_MXS) += mxs_i2c.o  obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o -obj-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o  obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o  obj-$(CONFIG_U8500_I2C) += u8500_i2c.o  obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o @@ -24,6 +23,7 @@ obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o  obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o  obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o  obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o +obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o  obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o  obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o  obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o diff --git a/drivers/i2c/fti2c010.c b/drivers/i2c/fti2c010.c index ddeb941fa..fb9fa353d 100644 --- a/drivers/i2c/fti2c010.c +++ b/drivers/i2c/fti2c010.c @@ -13,67 +13,78 @@  #include "fti2c010.h" -#ifndef CONFIG_HARD_I2C -#error "fti2c010: CONFIG_HARD_I2C is not defined" +#ifndef CONFIG_SYS_I2C_SPEED +#define CONFIG_SYS_I2C_SPEED    5000  #endif -#ifndef CONFIG_SYS_I2C_SPEED -#define CONFIG_SYS_I2C_SPEED    50000 +#ifndef CONFIG_SYS_I2C_SLAVE +#define CONFIG_SYS_I2C_SLAVE    0  #endif -#ifndef CONFIG_FTI2C010_FREQ -#define CONFIG_FTI2C010_FREQ    clk_get_rate("I2C") +#ifndef CONFIG_FTI2C010_CLOCK +#define CONFIG_FTI2C010_CLOCK   clk_get_rate("I2C")  #endif -/* command timeout */ -#define CFG_CMD_TIMEOUT         10 /* ms */ +#ifndef CONFIG_FTI2C010_TIMEOUT +#define CONFIG_FTI2C010_TIMEOUT 10 /* ms */ +#endif -/* 7-bit chip address + 1-bit read/write */ -#define I2C_RD(chip)            ((((chip) << 1) & 0xff) | 1) -#define I2C_WR(chip)            (((chip) << 1) & 0xff) +/* 7-bit dev address + 1-bit read/write */ +#define I2C_RD(dev)             ((((dev) << 1) & 0xfe) | 1) +#define I2C_WR(dev)             (((dev) << 1) & 0xfe)  struct fti2c010_chip { -	void __iomem *regs; -	uint bus; -	uint speed; +	struct fti2c010_regs *regs;  };  static struct fti2c010_chip chip_list[] = {  	{ -		.bus  = 0, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE,  	}, -#ifdef CONFIG_I2C_MULTI_BUS -# ifdef CONFIG_FTI2C010_BASE1 +#ifdef CONFIG_FTI2C010_BASE1  	{ -		.bus  = 1, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE1, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE1,  	}, -# endif -# ifdef CONFIG_FTI2C010_BASE2 +#endif +#ifdef CONFIG_FTI2C010_BASE2  	{ -		.bus  = 2, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE2, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE2,  	}, -# endif -# ifdef CONFIG_FTI2C010_BASE3 +#endif +#ifdef CONFIG_FTI2C010_BASE3  	{ -		.bus  = 3, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE3, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE3,  	}, -# endif -#endif  /* #ifdef CONFIG_I2C_MULTI_BUS */ +#endif  }; -static struct fti2c010_chip *curr = chip_list; +static int fti2c010_reset(struct fti2c010_chip *chip) +{ +	ulong ts; +	int ret = -1; +	struct fti2c010_regs *regs = chip->regs; + +	writel(CR_I2CRST, ®s->cr); +	for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) { +		if (!(readl(®s->cr) & CR_I2CRST)) { +			ret = 0; +			break; +		} +	} -static int fti2c010_wait(uint32_t mask) +	if (ret) +		printf("fti2c010: reset timeout\n"); + +	return ret; +} + +static int fti2c010_wait(struct fti2c010_chip *chip, uint32_t mask)  {  	int ret = -1;  	uint32_t stat, ts; -	struct fti2c010_regs *regs = curr->regs; +	struct fti2c010_regs *regs = chip->regs; -	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { +	for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) {  		stat = readl(®s->sr);  		if ((stat & mask) == mask) {  			ret = 0; @@ -84,88 +95,124 @@ static int fti2c010_wait(uint32_t mask)  	return ret;  } -/* - * u-boot I2C API - */ +static unsigned int set_i2c_bus_speed(struct fti2c010_chip *chip, +	unsigned int speed) +{ +	struct fti2c010_regs *regs = chip->regs; +	unsigned int clk = CONFIG_FTI2C010_CLOCK; +	unsigned int gsr = 0; +	unsigned int tsr = 32; +	unsigned int div, rate; + +	for (div = 0; div < 0x3ffff; ++div) { +		/* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ +		rate = clk / (2 * (div + 2) + gsr); +		if (rate <= speed) +			break; +	} + +	writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); +	writel(CDR_DIV(div), ®s->cdr); + +	return rate; +}  /*   * Initialization, must be called once on start up, may be called   * repeatedly to change the speed and slave addresses.   */ -void i2c_init(int speed, int slaveaddr) +static void fti2c010_init(struct i2c_adapter *adap, int speed, int slaveaddr)  { -	if (speed || !curr->speed) -		i2c_set_bus_speed(speed); +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; -	/* if slave mode disabled */ -	if (!slaveaddr) +	if (adap->init_done)  		return; -	/* -	 * TODO: -	 * Implement slave mode, but is it really necessary? -	 */ +#ifdef CONFIG_SYS_I2C_INIT_BOARD +	/* Call board specific i2c bus reset routine before accessing the +	 * environment, which might be in a chip on that bus. For details +	 * about this problem see doc/I2C_Edge_Conditions. +	*/ +	i2c_init_board(); +#endif + +	/* master init */ + +	fti2c010_reset(chip); + +	set_i2c_bus_speed(chip, speed); + +	/* slave init, don't care */ + +#ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT +	/* Call board specific i2c bus reset routine AFTER the bus has been +	 * initialized. Use either this callpoint or i2c_init_board; +	 * which is called before fti2c010_init operations. +	 * For details about this problem see doc/I2C_Edge_Conditions. +	*/ +	i2c_board_late_init(); +#endif  }  /*   * Probe the given I2C chip address.  Returns 0 if a chip responded,   * not 0 on failure.   */ -int i2c_probe(uchar chip) +static int fti2c010_probe(struct i2c_adapter *adap, u8 dev)  { +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	struct fti2c010_regs *regs = chip->regs;  	int ret; -	struct fti2c010_regs *regs = curr->regs; - -	i2c_init(0, 0);  	/* 1. Select slave device (7bits Address + 1bit R/W) */ -	writel(I2C_WR(chip), ®s->dr); +	writel(I2C_WR(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret;  	/* 2. Select device register */  	writel(0, ®s->dr);  	writel(CR_ENABLE | CR_TBEN, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	return ret;  } -/* - * Read/Write interface: - *   chip:    I2C chip address, range 0..127 - *   addr:    Memory (register) address within the chip - *   alen:    Number of bytes to use for addr (typically 1, 2 for larger - *              memories, 0 for register type devices with only one - *              register) - *   buffer:  Where to read/write the data - *   len:     How many bytes to read/write - * - *   Returns: 0 on success, not 0 on failure - */ -int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +static void to_i2c_addr(u8 *buf, uint32_t addr, int alen) +{ +	int i, shift; + +	if (!buf || alen <= 0) +		return; + +	/* MSB first */ +	i = 0; +	shift = (alen - 1) * 8; +	while (alen-- > 0) { +		buf[i] = (u8)(addr >> shift); +		shift -= 8; +	} +} + +static int fti2c010_read(struct i2c_adapter *adap, +			u8 dev, uint addr, int alen, uchar *buf, int len)  { +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	struct fti2c010_regs *regs = chip->regs;  	int ret, pos;  	uchar paddr[4]; -	struct fti2c010_regs *regs = curr->regs; -	i2c_init(0, 0); - -	paddr[0] = (addr >> 0)  & 0xFF; -	paddr[1] = (addr >> 8)  & 0xFF; -	paddr[2] = (addr >> 16) & 0xFF; -	paddr[3] = (addr >> 24) & 0xFF; +	to_i2c_addr(paddr, addr, alen);  	/*  	 * Phase A. Set register address  	 */  	/* A.1 Select slave device (7bits Address + 1bit R/W) */ -	writel(I2C_WR(chip), ®s->dr); +	writel(I2C_WR(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret; @@ -175,7 +222,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  		writel(paddr[pos], ®s->dr);  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(SR_DT); +		ret = fti2c010_wait(chip, SR_DT);  		if (ret)  			return ret;  	} @@ -185,9 +232,9 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  	 */  	/* B.1 Select slave device (7bits Address + 1bit R/W) */ -	writel(I2C_RD(chip), ®s->dr); +	writel(I2C_RD(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret; @@ -201,7 +248,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  			stat |= SR_ACK;  		}  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(stat); +		ret = fti2c010_wait(chip, stat);  		if (ret)  			break;  		buf[pos] = (uchar)(readl(®s->dr) & 0xFF); @@ -210,39 +257,24 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  	return ret;  } -/* - * Read/Write interface: - *   chip:    I2C chip address, range 0..127 - *   addr:    Memory (register) address within the chip - *   alen:    Number of bytes to use for addr (typically 1, 2 for larger - *              memories, 0 for register type devices with only one - *              register) - *   buffer:  Where to read/write the data - *   len:     How many bytes to read/write - * - *   Returns: 0 on success, not 0 on failure - */ -int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) +static int fti2c010_write(struct i2c_adapter *adap, +			u8 dev, uint addr, int alen, u8 *buf, int len)  { +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	struct fti2c010_regs *regs = chip->regs;  	int ret, pos;  	uchar paddr[4]; -	struct fti2c010_regs *regs = curr->regs; -	i2c_init(0, 0); - -	paddr[0] = (addr >> 0)  & 0xFF; -	paddr[1] = (addr >> 8)  & 0xFF; -	paddr[2] = (addr >> 16) & 0xFF; -	paddr[3] = (addr >> 24) & 0xFF; +	to_i2c_addr(paddr, addr, alen);  	/*  	 * Phase A. Set register address  	 *  	 * A.1 Select slave device (7bits Address + 1bit R/W)  	 */ -	writel(I2C_WR(chip), ®s->dr); +	writel(I2C_WR(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret; @@ -252,7 +284,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)  		writel(paddr[pos], ®s->dr);  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(SR_DT); +		ret = fti2c010_wait(chip, SR_DT);  		if (ret)  			return ret;  	} @@ -267,7 +299,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)  			ctrl |= CR_STOP;  		writel(buf[pos], ®s->dr);  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(SR_DT); +		ret = fti2c010_wait(chip, SR_DT);  		if (ret)  			break;  	} @@ -275,94 +307,40 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)  	return ret;  } -/* - * Functions for setting the current I2C bus and its speed - */ -#ifdef CONFIG_I2C_MULTI_BUS - -/* - * i2c_set_bus_num: - * - *  Change the active I2C bus.  Subsequent read/write calls will - *  go to this one. - * - *    bus - bus index, zero based - * - *    Returns: 0 on success, not 0 on failure - */ -int i2c_set_bus_num(uint bus) -{ -	if (bus >= ARRAY_SIZE(chip_list)) -		return -1; -	curr = chip_list + bus; -	i2c_init(0, 0); -	return 0; -} - -/* - * i2c_get_bus_num: - * - *  Returns index of currently active I2C bus.  Zero-based. - */ - -uint i2c_get_bus_num(void) -{ -	return curr->bus; -} - -#endif    /* #ifdef CONFIG_I2C_MULTI_BUS */ - -/* - * i2c_set_bus_speed: - * - *  Change the speed of the active I2C bus - * - *    speed - bus speed in Hz - * - *    Returns: 0 on success, not 0 on failure - */ -int i2c_set_bus_speed(uint speed) +static unsigned int fti2c010_set_bus_speed(struct i2c_adapter *adap, +			unsigned int speed)  { -	struct fti2c010_regs *regs = curr->regs; -	uint clk = CONFIG_FTI2C010_FREQ; -	uint gsr = 0, tsr = 32; -	uint spd, div; - -	if (!speed) -		speed = CONFIG_SYS_I2C_SPEED; - -	for (div = 0; div < 0x3ffff; ++div) { -		/* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ -		spd = clk / (2 * (div + 2) + gsr); -		if (spd <= speed) -			break; -	} - -	if (curr->speed == spd) -		return 0; - -	writel(CR_I2CRST, ®s->cr); -	mdelay(100); -	if (readl(®s->cr) & CR_I2CRST) { -		printf("fti2c010: reset timeout\n"); -		return -1; -	} +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	int ret; -	curr->speed = spd; +	fti2c010_reset(chip); +	ret = set_i2c_bus_speed(chip, speed); -	writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); -	writel(CDR_DIV(div), ®s->cdr); - -	return 0; +	return ret;  }  /* - * i2c_get_bus_speed: - * - *  Returns speed of currently active I2C bus in Hz + * Register i2c adapters   */ - -uint i2c_get_bus_speed(void) -{ -	return curr->speed; -} +U_BOOT_I2C_ADAP_COMPLETE(i2c_0, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			0) +#ifdef CONFIG_FTI2C010_BASE1 +U_BOOT_I2C_ADAP_COMPLETE(i2c_1, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			1) +#endif +#ifdef CONFIG_FTI2C010_BASE2 +U_BOOT_I2C_ADAP_COMPLETE(i2c_2, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			2) +#endif +#ifdef CONFIG_FTI2C010_BASE3 +U_BOOT_I2C_ADAP_COMPLETE(i2c_3, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			3) +#endif diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index 3d38c035b..c7840049b 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -158,7 +158,6 @@ static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)  	udelay(1000);  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  }  static void flush_fifo(struct i2c_adapter *adap) @@ -198,8 +197,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)  		return res;  	/* No data transfer, slave addr only */ -	writew(0, &i2c_base->cnt); -	/* Set slave address */  	writew(chip, &i2c_base->sa);  	/* Stop bit needed here */  	writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | @@ -234,7 +231,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)  pr_exit:  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  	return res;  } @@ -372,7 +368,6 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,  rd_exit:  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  	return i2c_error;  } @@ -473,7 +468,6 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,  wr_exit:  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  	return i2c_error;  } diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index f77a9d1a1..fd328f054 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -23,8 +23,6 @@  #include <i2c.h>  #include "s3c24x0_i2c.h" -#ifdef CONFIG_HARD_I2C -  #define	I2C_WRITE	0  #define I2C_READ	1 @@ -127,7 +125,6 @@   * For SPL boot some boards need i2c before SDRAM is initialised so force   * variables to live in SRAM   */ -static unsigned int g_current_bus __attribute__((section(".data")));  static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]  			__attribute__((section(".data"))); @@ -254,17 +251,17 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c)  	writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon);  } -static struct s3c24x0_i2c *get_base_i2c(void) +static struct s3c24x0_i2c *get_base_i2c(int bus)  {  #ifdef CONFIG_EXYNOS4  	struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()  							+ (EXYNOS4_I2C_SPACING -							* g_current_bus)); +							* bus));  	return i2c;  #elif defined CONFIG_EXYNOS5  	struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()  							+ (EXYNOS5_I2C_SPACING -							* g_current_bus)); +							* bus));  	return i2c;  #else  	return s3c24x0_get_base_i2c(); @@ -298,7 +295,6 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)  	writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);  } -#ifdef CONFIG_I2C_MULTI_BUS  static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)  {  	struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; @@ -307,8 +303,10 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)  	unsigned int i = 0, utemp0 = 0, utemp1 = 0;  	unsigned int t_ftl_cycle; -#if defined CONFIG_EXYNOS5 +#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)  	clkin = get_i2c_clk(); +#else +	clkin = get_PCLK();  #endif  	/* FPCLK / FI2C =  	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE @@ -330,7 +328,6 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)  	}  	return -1;  } -#endif  static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus)  { @@ -401,49 +398,18 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus)  	hsi2c_ch_init(i2c_bus);  } -/* - * MULTI BUS I2C support - */ - -#ifdef CONFIG_I2C_MULTI_BUS -int i2c_set_bus_num(unsigned int bus) -{ -	struct s3c24x0_i2c_bus *i2c_bus; - -	i2c_bus = get_bus(bus); -	if (!i2c_bus) -		return -1; -	g_current_bus = bus; - -	if (i2c_bus->is_highspeed) { -		if (hsi2c_get_clk_details(i2c_bus)) -			return -1; -		hsi2c_ch_init(i2c_bus); -	} else { -		i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, -						CONFIG_SYS_I2C_SLAVE); -	} - -	return 0; -} - -unsigned int i2c_get_bus_num(void) -{ -	return g_current_bus; -} -#endif - -void i2c_init(int speed, int slaveadd) +static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)  {  	struct s3c24x0_i2c *i2c; +	struct s3c24x0_i2c_bus *bus; +  #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)  	struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();  #endif  	ulong start_time = get_timer(0);  	/* By default i2c channel 0 is the current bus */ -	g_current_bus = 0; -	i2c = get_base_i2c(); +	i2c = get_base_i2c(adap->hwadapnr);  	/*  	 * In case the previous transfer is still going, wait to give it a @@ -505,6 +471,10 @@ void i2c_init(int speed, int slaveadd)  	}  #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */  	i2c_ch_init(i2c, speed, slaveadd); + +	bus = &i2c_bus[adap->hwadapnr]; +	bus->active = true; +	bus->regs = i2c;  }  /* @@ -728,6 +698,40 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c,  	return rv;  } +static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, +					  unsigned int speed) +{ +	struct s3c24x0_i2c_bus *i2c_bus; + +	i2c_bus = get_bus(adap->hwadapnr); +	if (!i2c_bus) +		return -1; + +	i2c_bus->clock_frequency = speed; + +	if (i2c_bus->is_highspeed) { +		if (hsi2c_get_clk_details(i2c_bus)) +			return -1; +		hsi2c_ch_init(i2c_bus); +	} else { +		i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, +			    CONFIG_SYS_I2C_S3C24X0_SLAVE); +	} + +	return 0; +} + +#ifdef CONFIG_EXYNOS5 +static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) +{ +	/* This will override the speed selected in the fdt for that port */ +	debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); +	if (i2c_set_bus_speed(speed)) +		printf("i2c_init: failed to init bus %d for speed = %d\n", +						adap->hwadapnr, speed); +} +#endif +  /*   * cmd_type is 0 for write, 1 for read.   * @@ -840,13 +844,13 @@ bailout:  	return result;  } -int i2c_probe(uchar chip) +static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)  {  	struct s3c24x0_i2c_bus *i2c_bus;  	uchar buf[1];  	int ret; -	i2c_bus = get_bus(g_current_bus); +	i2c_bus = get_bus(adap->hwadapnr);  	if (!i2c_bus)  		return -1;  	buf[0] = 0; @@ -864,11 +868,11 @@ int i2c_probe(uchar chip)  				I2C_READ, chip << 1, 0, 0, buf, 1);  	} -  	return ret != I2C_OK;  } -int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, +			    int alen, uchar *buffer, int len)  {  	struct s3c24x0_i2c_bus *i2c_bus;  	uchar xaddr[4]; @@ -902,7 +906,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)  		chip |= ((addr >> (alen * 8)) &  			 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);  #endif -	i2c_bus = get_bus(g_current_bus); +	i2c_bus = get_bus(adap->hwadapnr);  	if (!i2c_bus)  		return -1; @@ -922,7 +926,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)  	return 0;  } -int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, +			 int alen, uchar *buffer, int len)  {  	struct s3c24x0_i2c_bus *i2c_bus;  	uchar xaddr[4]; @@ -955,7 +960,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)  		chip |= ((addr >> (alen * 8)) &  			 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);  #endif -	i2c_bus = get_bus(g_current_bus); +	i2c_bus = get_bus(adap->hwadapnr);  	if (!i2c_bus)  		return -1; @@ -1001,8 +1006,8 @@ static void process_nodes(const void *blob, int node_list[], int count,  		bus->id = pinmux_decode_periph_id(blob, node);  		bus->clock_frequency = fdtdec_get_int(blob, node, -						      "clock-frequency", -						      CONFIG_SYS_I2C_SPEED); +						"clock-frequency", +						CONFIG_SYS_I2C_S3C24X0_SPEED);  		bus->node = node;  		bus->bus_num = i;  		exynos_pinmux_config(bus->id, 0); @@ -1044,7 +1049,6 @@ int i2c_get_bus_num_fdt(int node)  	return -1;  } -#ifdef CONFIG_I2C_MULTI_BUS  int i2c_reset_port_fdt(const void *blob, int node)  {  	struct s3c24x0_i2c_bus *i2c_bus; @@ -1068,12 +1072,178 @@ int i2c_reset_port_fdt(const void *blob, int node)  		hsi2c_ch_init(i2c_bus);  	} else {  		i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, -						CONFIG_SYS_I2C_SLAVE); +			    CONFIG_SYS_I2C_S3C24X0_SLAVE);  	}  	return 0;  }  #endif -#endif -#endif /* CONFIG_HARD_I2C */ +/* + * Register s3c24x0 i2c adapters + */ +#if defined(CONFIG_EXYNOS5420) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +U_BOOT_I2C_ADAP_COMPLETE(i2c09, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) +U_BOOT_I2C_ADAP_COMPLETE(i2c10, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) +#elif defined(CONFIG_EXYNOS5250) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +U_BOOT_I2C_ADAP_COMPLETE(i2c09, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) +U_BOOT_I2C_ADAP_COMPLETE(s3c10, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) +#elif defined(CONFIG_EXYNOS4) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +#else +U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +#endif diff --git a/drivers/misc/cros_ec_spi.c b/drivers/misc/cros_ec_spi.c index 202acf258..2fc911025 100644 --- a/drivers/misc/cros_ec_spi.c +++ b/drivers/misc/cros_ec_spi.c @@ -135,8 +135,7 @@ int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob)   */  int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob)  { -	dev->spi = spi_setup_slave_fdt(blob, dev->parent_node, -				       dev->cs, dev->max_frequency, 0); +	dev->spi = spi_setup_slave_fdt(blob, dev->parent_node, dev->node);  	if (!dev->spi) {  		debug("%s: Could not setup SPI slave\n", __func__);  		return -1; diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index a7ae38dad..1ed26cab3 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o  obj-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o  obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o  obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o +obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o  obj-$(CONFIG_GENERIC_MMC) += mmc.o  obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o  obj-$(CONFIG_MMC_SPI) += mmc_spi.o diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 1e0f72bbe..19d9b0b89 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -11,7 +11,6 @@  #include <mmc.h>  #include <dwmmc.h>  #include <asm-generic/errno.h> -#include <asm/arch/dwmmc.h>  #define PAGE_SIZE 4096 @@ -300,17 +299,9 @@ static void dwmci_set_ios(struct mmc *mmc)  static int dwmci_init(struct mmc *mmc)  {  	struct dwmci_host *host = (struct dwmci_host *)mmc->priv; -	u32 fifo_size; -	if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) { -		dwmci_writel(host, EMMCP_MPSBEGIN0, 0); -		dwmci_writel(host, EMMCP_SEND0, 0); -		dwmci_writel(host, EMMCP_CTRL0, -			     MPSCTRL_SECURE_READ_BIT | -			     MPSCTRL_SECURE_WRITE_BIT | -			     MPSCTRL_NON_SECURE_READ_BIT | -			     MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID); -	} +	if (host->board_init) +		host->board_init(host);  	dwmci_writel(host, DWMCI_PWREN, 1); @@ -330,13 +321,9 @@ static int dwmci_init(struct mmc *mmc)  	dwmci_writel(host, DWMCI_IDINTEN, 0);  	dwmci_writel(host, DWMCI_BMOD, 1); -	if (!host->fifoth_val) { -		fifo_size = dwmci_readl(host, DWMCI_FIFOTH); -		fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1; -		host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) | -			TX_WMARK(fifo_size / 2); +	if (host->fifoth_val) { +		dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);  	} -	dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);  	dwmci_writel(host, DWMCI_CLKENA, 0);  	dwmci_writel(host, DWMCI_CLKSRC, 0); diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index a0f1511cb..b3e5c5e5e 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -34,6 +34,19 @@ unsigned int exynos_dwmci_get_clk(int dev_index)  	return get_mmc_clk(dev_index);  } +static void exynos_dwmci_board_init(struct dwmci_host *host) +{ +	if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) { +		dwmci_writel(host, EMMCP_MPSBEGIN0, 0); +		dwmci_writel(host, EMMCP_SEND0, 0); +		dwmci_writel(host, EMMCP_CTRL0, +			     MPSCTRL_SECURE_READ_BIT | +			     MPSCTRL_SECURE_WRITE_BIT | +			     MPSCTRL_NON_SECURE_READ_BIT | +			     MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID); +	} +} +  /*   * This function adds the mmc channel to be registered with mmc core.   * index -	mmc channel number. @@ -65,6 +78,7 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)  #ifdef CONFIG_EXYNOS5420  	host->quirks = DWMCI_QUIRK_DISABLE_SMU;  #endif +	host->board_init = exynos_dwmci_board_init;  	if (clksel) {  		host->clksel_val = clksel; diff --git a/drivers/mmc/fsl_esdhc_spl.c b/drivers/mmc/fsl_esdhc_spl.c index 65c52a22d..8fc263f4f 100644 --- a/drivers/mmc/fsl_esdhc_spl.c +++ b/drivers/mmc/fsl_esdhc_spl.c @@ -42,6 +42,10 @@ void __noreturn mmc_boot(void)  		hang();  	} +#ifdef CONFIG_FSL_CORENET +	offset = CONFIG_SYS_MMC_U_BOOT_OFFS; +	code_len = CONFIG_SYS_MMC_U_BOOT_SIZE; +#else  	blklen = mmc->read_bl_len;  	tmp_buf = malloc(blklen);  	if (!tmp_buf) { @@ -91,6 +95,7 @@ void __noreturn mmc_boot(void)  	/*  	* Load U-Boot image from mmc into RAM  	*/ +#endif  	blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;  	blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len;  	err = mmc->block_dev.block_read(0, blk_start, blk_cnt, diff --git a/drivers/mmc/ftsdc021_sdhci.c b/drivers/mmc/ftsdc021_sdhci.c new file mode 100644 index 000000000..1f6cdba17 --- /dev/null +++ b/drivers/mmc/ftsdc021_sdhci.c @@ -0,0 +1,33 @@ +/* + * (C) Copyright 2013 Faraday Technology + * Kuo-Jung Su <dantesu@faraday-tech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <malloc.h> +#include <sdhci.h> + +#ifndef CONFIG_FTSDC021_CLOCK +#define CONFIG_FTSDC021_CLOCK   clk_get_rate("MMC") +#endif + +int ftsdc021_sdhci_init(u32 regbase) +{ +	struct sdhci_host *host = NULL; +	uint32_t freq = CONFIG_FTSDC021_CLOCK; + +	host = calloc(1, sizeof(struct sdhci_host)); +	if (!host) { +		puts("sdh_host malloc fail!\n"); +		return 1; +	} + +	host->name = "FTSDC021"; +	host->ioaddr = (void __iomem *)regbase; +	host->quirks = 0; +	add_sdhci(host, freq, 0); + +	return 0; +} diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile index 1bbeb7da3..26483a23f 100644 --- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -13,4 +13,5 @@ endif  obj-$(CONFIG_CMD_SF)        += sf.o  obj-$(CONFIG_SPI_FLASH) += sf_probe.o sf_ops.o  obj-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.o +obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o  obj-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o diff --git a/drivers/mtd/spi/fsl_espi_spl.c b/drivers/mtd/spi/fsl_espi_spl.c index 6263d8c22..e5ac79b95 100644 --- a/drivers/mtd/spi/fsl_espi_spl.c +++ b/drivers/mtd/spi/fsl_espi_spl.c @@ -31,6 +31,10 @@ void spi_boot(void)  		hang();  	} +#ifdef CONFIG_FSL_CORENET +	offset = CONFIG_SYS_SPI_FLASH_U_BOOT_OFFS; +	code_len = CONFIG_SYS_SPI_FLASH_U_BOOT_SIZE; +#else  	/*  	* Load U-Boot image from SPI flash into RAM  	*/ @@ -50,6 +54,7 @@ void spi_boot(void)  	code_len = *(u32 *)(buf + ESPI_BOOT_IMAGE_SIZE);  	/* Skip spl code */  	code_len = code_len - CONFIG_SPL_MAX_SIZE; +#endif  	/* copy code to DDR */  	spi_flash_read(flash, offset, code_len,  		       (void *)CONFIG_SYS_SPI_FLASH_U_BOOT_DST); diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c new file mode 100644 index 000000000..a62ef4cbb --- /dev/null +++ b/drivers/mtd/spi/sandbox.c @@ -0,0 +1,483 @@ +/* + * Simulate a SPI flash + * + * Copyright (c) 2011-2013 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> +#include <os.h> + +#include <spi_flash.h> +#include "sf_internal.h" + +#include <asm/getopt.h> +#include <asm/spi.h> +#include <asm/state.h> + +/* + * The different states that our SPI flash transitions between. + * We need to keep track of this across multiple xfer calls since + * the SPI bus could possibly call down into us multiple times. + */ +enum sandbox_sf_state { +	SF_CMD,   /* default state -- we're awaiting a command */ +	SF_ID,    /* read the flash's (jedec) ID code */ +	SF_ADDR,  /* processing the offset in the flash to read/etc... */ +	SF_READ,  /* reading data from the flash */ +	SF_WRITE, /* writing data to the flash, i.e. page programming */ +	SF_ERASE, /* erase the flash */ +	SF_READ_STATUS, /* read the flash's status register */ +	SF_READ_STATUS1, /* read the flash's status register upper 8 bits*/ +}; + +static const char *sandbox_sf_state_name(enum sandbox_sf_state state) +{ +	static const char * const states[] = { +		"CMD", "ID", "ADDR", "READ", "WRITE", "ERASE", "READ_STATUS", +	}; +	return states[state]; +} + +/* Bits for the status register */ +#define STAT_WIP	(1 << 0) +#define STAT_WEL	(1 << 1) + +/* Assume all SPI flashes have 3 byte addresses since they do atm */ +#define SF_ADDR_LEN	3 + +struct sandbox_spi_flash_erase_commands { +	u8 cmd; +	u32 size; +}; +#define IDCODE_LEN 5 +#define MAX_ERASE_CMDS 3 +struct sandbox_spi_flash_data { +	const char *name; +	u8 idcode[IDCODE_LEN]; +	u32 size; +	const struct sandbox_spi_flash_erase_commands +						erase_cmds[MAX_ERASE_CMDS]; +}; + +/* Structure describing all the flashes we know how to emulate */ +static const struct sandbox_spi_flash_data sandbox_sf_flashes[] = { +	{ +		"M25P16", { 0x20, 0x20, 0x15 }, (2 << 20), +		{	/* erase commands */ +			{ 0xd8, (64 << 10), }, /* sector */ +			{ 0xc7, (2 << 20), }, /* bulk */ +		}, +	}, +	{ +		"W25Q32", { 0xef, 0x40, 0x16 }, (4 << 20), +		{	/* erase commands */ +			{ 0x20, (4 << 10), }, /* 4KB */ +			{ 0xd8, (64 << 10), }, /* sector */ +			{ 0xc7, (4 << 20), }, /* bulk */ +		}, +	}, +	{ +		"W25Q128", { 0xef, 0x40, 0x18 }, (16 << 20), +		{	/* erase commands */ +			{ 0x20, (4 << 10), }, /* 4KB */ +			{ 0xd8, (64 << 10), }, /* sector */ +			{ 0xc7, (16 << 20), }, /* bulk */ +		}, +	}, +}; + +/* Used to quickly bulk erase backing store */ +static u8 sandbox_sf_0xff[0x1000]; + +/* Internal state data for each SPI flash */ +struct sandbox_spi_flash { +	/* +	 * As we receive data over the SPI bus, our flash transitions +	 * between states.  For example, we start off in the SF_CMD +	 * state where the first byte tells us what operation to perform +	 * (such as read or write the flash).  But the operation itself +	 * can go through a few states such as first reading in the +	 * offset in the flash to perform the requested operation. +	 * Thus "state" stores the exact state that our machine is in +	 * while "cmd" stores the overall command we're processing. +	 */ +	enum sandbox_sf_state state; +	uint cmd; +	const void *cmd_data; +	/* Current position in the flash; used when reading/writing/etc... */ +	uint off; +	/* How many address bytes we've consumed */ +	uint addr_bytes, pad_addr_bytes; +	/* The current flash status (see STAT_XXX defines above) */ +	u16 status; +	/* Data describing the flash we're emulating */ +	const struct sandbox_spi_flash_data *data; +	/* The file on disk to serv up data from */ +	int fd; +}; + +static int sandbox_sf_setup(void **priv, const char *spec) +{ +	/* spec = idcode:file */ +	struct sandbox_spi_flash *sbsf; +	const char *file; +	size_t i, len, idname_len; +	const struct sandbox_spi_flash_data *data; + +	file = strchr(spec, ':'); +	if (!file) { +		printf("sandbox_sf: unable to parse file\n"); +		goto error; +	} +	idname_len = file - spec; +	++file; + +	for (i = 0; i < ARRAY_SIZE(sandbox_sf_flashes); ++i) { +		data = &sandbox_sf_flashes[i]; +		len = strlen(data->name); +		if (idname_len != len) +			continue; +		if (!memcmp(spec, data->name, len)) +			break; +	} +	if (i == ARRAY_SIZE(sandbox_sf_flashes)) { +		printf("sandbox_sf: unknown flash '%*s'\n", (int)idname_len, +		       spec); +		goto error; +	} + +	if (sandbox_sf_0xff[0] == 0x00) +		memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff)); + +	sbsf = calloc(sizeof(*sbsf), 1); +	if (!sbsf) { +		printf("sandbox_sf: out of memory\n"); +		goto error; +	} + +	sbsf->fd = os_open(file, 02); +	if (sbsf->fd == -1) { +		free(sbsf); +		printf("sandbox_sf: unable to open file '%s'\n", file); +		goto error; +	} + +	sbsf->data = data; + +	*priv = sbsf; +	return 0; + + error: +	return 1; +} + +static void sandbox_sf_free(void *priv) +{ +	struct sandbox_spi_flash *sbsf = priv; + +	os_close(sbsf->fd); +	free(sbsf); +} + +static void sandbox_sf_cs_activate(void *priv) +{ +	struct sandbox_spi_flash *sbsf = priv; + +	debug("sandbox_sf: CS activated; state is fresh!\n"); + +	/* CS is asserted, so reset state */ +	sbsf->off = 0; +	sbsf->addr_bytes = 0; +	sbsf->pad_addr_bytes = 0; +	sbsf->state = SF_CMD; +	sbsf->cmd = SF_CMD; +} + +static void sandbox_sf_cs_deactivate(void *priv) +{ +	debug("sandbox_sf: CS deactivated; cmd done processing!\n"); +} + +/* Figure out what command this stream is telling us to do */ +static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx, +				  u8 *tx) +{ +	enum sandbox_sf_state oldstate = sbsf->state; + +	/* We need to output a byte for the cmd byte we just ate */ +	sandbox_spi_tristate(tx, 1); + +	sbsf->cmd = rx[0]; +	switch (sbsf->cmd) { +	case CMD_READ_ID: +		sbsf->state = SF_ID; +		sbsf->cmd = SF_ID; +		break; +	case CMD_READ_ARRAY_FAST: +		sbsf->pad_addr_bytes = 1; +	case CMD_READ_ARRAY_SLOW: +	case CMD_PAGE_PROGRAM: + state_addr: +		sbsf->state = SF_ADDR; +		break; +	case CMD_WRITE_DISABLE: +		debug(" write disabled\n"); +		sbsf->status &= ~STAT_WEL; +		break; +	case CMD_READ_STATUS: +		sbsf->state = SF_READ_STATUS; +		break; +	case CMD_READ_STATUS1: +		sbsf->state = SF_READ_STATUS1; +		break; +	case CMD_WRITE_ENABLE: +		debug(" write enabled\n"); +		sbsf->status |= STAT_WEL; +		break; +	default: { +		size_t i; + +		/* handle erase commands first */ +		for (i = 0; i < MAX_ERASE_CMDS; ++i) { +			const struct sandbox_spi_flash_erase_commands * +				erase_cmd = &sbsf->data->erase_cmds[i]; + +			if (erase_cmd->cmd == 0x00) +				continue; +			if (sbsf->cmd != erase_cmd->cmd) +				continue; + +			sbsf->cmd_data = erase_cmd; +			goto state_addr; +		} + +		debug(" cmd unknown: %#x\n", sbsf->cmd); +		return 1; +	} +	} + +	if (oldstate != sbsf->state) +		debug(" cmd: transition to %s state\n", +		      sandbox_sf_state_name(sbsf->state)); + +	return 0; +} + +int sandbox_erase_part(struct sandbox_spi_flash *sbsf, int size) +{ +	int todo; +	int ret; + +	while (size > 0) { +		todo = min(size, sizeof(sandbox_sf_0xff)); +		ret = os_write(sbsf->fd, sandbox_sf_0xff, todo); +		if (ret != todo) +			return ret; +		size -= todo; +	} + +	return 0; +} + +static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx, +		uint bytes) +{ +	struct sandbox_spi_flash *sbsf = priv; +	uint cnt, pos = 0; +	int ret; + +	debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state, +	      sandbox_sf_state_name(sbsf->state), bytes); + +	if (sbsf->state == SF_CMD) { +		/* Figure out the initial state */ +		if (sandbox_sf_process_cmd(sbsf, rx, tx)) +			return 1; +		++pos; +	} + +	/* Process the remaining data */ +	while (pos < bytes) { +		switch (sbsf->state) { +		case SF_ID: { +			u8 id; + +			debug(" id: off:%u tx:", sbsf->off); +			if (sbsf->off < IDCODE_LEN) +				id = sbsf->data->idcode[sbsf->off]; +			else +				id = 0; +			debug("%02x\n", id); +			tx[pos++] = id; +			++sbsf->off; +			break; +		} +		case SF_ADDR: +			debug(" addr: bytes:%u rx:%02x ", sbsf->addr_bytes, +			      rx[pos]); + +			if (sbsf->addr_bytes++ < SF_ADDR_LEN) +				sbsf->off = (sbsf->off << 8) | rx[pos]; +			debug("addr:%06x\n", sbsf->off); + +			sandbox_spi_tristate(&tx[pos++], 1); + +			/* See if we're done processing */ +			if (sbsf->addr_bytes < +					SF_ADDR_LEN + sbsf->pad_addr_bytes) +				break; + +			/* Next state! */ +			if (os_lseek(sbsf->fd, sbsf->off, OS_SEEK_SET) < 0) { +				puts("sandbox_sf: os_lseek() failed"); +				return 1; +			} +			switch (sbsf->cmd) { +			case CMD_READ_ARRAY_FAST: +			case CMD_READ_ARRAY_SLOW: +				sbsf->state = SF_READ; +				break; +			case CMD_PAGE_PROGRAM: +				sbsf->state = SF_WRITE; +				break; +			default: +				/* assume erase state ... */ +				sbsf->state = SF_ERASE; +				goto case_sf_erase; +			} +			debug(" cmd: transition to %s state\n", +			      sandbox_sf_state_name(sbsf->state)); +			break; +		case SF_READ: +			/* +			 * XXX: need to handle exotic behavior: +			 *      - reading past end of device +			 */ + +			cnt = bytes - pos; +			debug(" tx: read(%u)\n", cnt); +			ret = os_read(sbsf->fd, tx + pos, cnt); +			if (ret < 0) { +				puts("sandbox_spi: os_read() failed\n"); +				return 1; +			} +			pos += ret; +			break; +		case SF_READ_STATUS: +			debug(" read status: %#x\n", sbsf->status); +			cnt = bytes - pos; +			memset(tx + pos, sbsf->status, cnt); +			pos += cnt; +			break; +		case SF_READ_STATUS1: +			debug(" read status: %#x\n", sbsf->status); +			cnt = bytes - pos; +			memset(tx + pos, sbsf->status >> 8, cnt); +			pos += cnt; +			break; +		case SF_WRITE: +			/* +			 * XXX: need to handle exotic behavior: +			 *      - unaligned addresses +			 *      - more than a page (256) worth of data +			 *      - reading past end of device +			 */ +			if (!(sbsf->status & STAT_WEL)) { +				puts("sandbox_sf: write enable not set before write\n"); +				goto done; +			} + +			cnt = bytes - pos; +			debug(" rx: write(%u)\n", cnt); +			sandbox_spi_tristate(&tx[pos], cnt); +			ret = os_write(sbsf->fd, rx + pos, cnt); +			if (ret < 0) { +				puts("sandbox_spi: os_write() failed\n"); +				return 1; +			} +			pos += ret; +			sbsf->status &= ~STAT_WEL; +			break; +		case SF_ERASE: + case_sf_erase: { +			const struct sandbox_spi_flash_erase_commands * +						erase_cmd = sbsf->cmd_data; + +			if (!(sbsf->status & STAT_WEL)) { +				puts("sandbox_sf: write enable not set before erase\n"); +				goto done; +			} + +			/* verify address is aligned */ +			if (sbsf->off & (erase_cmd->size - 1)) { +				debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n", +				      erase_cmd->cmd, erase_cmd->size, +				      sbsf->off); +				sbsf->status &= ~STAT_WEL; +				goto done; +			} + +			debug(" sector erase addr: %u\n", sbsf->off); + +			cnt = bytes - pos; +			sandbox_spi_tristate(&tx[pos], cnt); +			pos += cnt; + +			/* +			 * TODO(vapier@gentoo.org): latch WIP in status, and +			 * delay before clearing it ? +			 */ +			ret = sandbox_erase_part(sbsf, erase_cmd->size); +			sbsf->status &= ~STAT_WEL; +			if (ret) { +				debug("sandbox_sf: Erase failed\n"); +				goto done; +			} +			goto done; +		} +		default: +			debug(" ??? no idea what to do ???\n"); +			goto done; +		} +	} + + done: +	return pos == bytes ? 0 : 1; +} + +static const struct sandbox_spi_emu_ops sandbox_sf_ops = { +	.setup         = sandbox_sf_setup, +	.free          = sandbox_sf_free, +	.cs_activate   = sandbox_sf_cs_activate, +	.cs_deactivate = sandbox_sf_cs_deactivate, +	.xfer          = sandbox_sf_xfer, +}; + +static int sandbox_cmdline_cb_spi_sf(struct sandbox_state *state, +				     const char *arg) +{ +	unsigned long bus, cs; +	const char *spec = sandbox_spi_parse_spec(arg, &bus, &cs); + +	if (!spec) +		return 1; + +	/* +	 * It is safe to not make a copy of 'spec' because it comes from the +	 * command line. +	 * +	 * TODO(sjg@chromium.org): It would be nice if we could parse the +	 * spec here, but the problem is that no U-Boot init has been done +	 * yet. Perhaps we can figure something out. +	 */ +	state->spi[bus][cs].ops = &sandbox_sf_ops; +	state->spi[bus][cs].spec = spec; +	return 0; +} +SANDBOX_CMDLINE_OPT(spi_sf, 1, "connect a SPI flash: <bus>:<cs>:<id>:<file>"); diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 732ddf836..d291746ed 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -28,6 +28,7 @@  #define CMD_PAGE_PROGRAM		0x02  #define CMD_WRITE_DISABLE		0x04  #define CMD_READ_STATUS			0x05 +#define CMD_READ_STATUS1		0x35  #define CMD_WRITE_ENABLE		0x06  #define CMD_READ_CONFIG			0x35  #define CMD_FLAG_STATUS			0x70 diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 5eb8ffe84..c1eb75489 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -13,6 +13,7 @@  #include <malloc.h>  #include <spi.h>  #include <spi_flash.h> +#include <asm/io.h>  #include "sf_internal.h" @@ -279,22 +280,19 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)  		debug("%s: Memory map must cover entire device\n", __func__);  		return -1;  	} -	flash->memory_map = (void *)addr; +	flash->memory_map = map_sysmem(addr, size);  	return 0;  }  #endif /* CONFIG_OF_CONTROL */ -struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, -		unsigned int max_hz, unsigned int spi_mode) +static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)  { -	struct spi_slave *spi;  	struct spi_flash *flash = NULL;  	u8 idcode[5];  	int ret;  	/* Setup spi_slave */ -	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);  	if (!spi) {  		printf("SF: Failed to set up slave\n");  		return NULL; @@ -358,6 +356,26 @@ err_claim_bus:  	return NULL;  } +struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, +		unsigned int max_hz, unsigned int spi_mode) +{ +	struct spi_slave *spi; + +	spi = spi_setup_slave(bus, cs, max_hz, spi_mode); +	return spi_flash_probe_slave(spi); +} + +#ifdef CONFIG_OF_SPI_FLASH +struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node, +				      int spi_node) +{ +	struct spi_slave *spi; + +	spi = spi_setup_slave_fdt(blob, slave_node, spi_node); +	return spi_flash_probe_slave(spi); +} +#endif +  void spi_flash_free(struct spi_flash *flash)  {  	spi_free_slave(flash->spi); diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 27902fe39..ed4ecd754 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_MXC_SPI) += mxc_spi.o  obj-$(CONFIG_MXS_SPI) += mxs_spi.o  obj-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o  obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o +obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o  obj-$(CONFIG_SOFT_SPI) += soft_spi.o  obj-$(CONFIG_SH_SPI) += sh_spi.o  obj-$(CONFIG_FSL_ESPI) += fsl_espi.o diff --git a/drivers/spi/bfin_spi.c b/drivers/spi/bfin_spi.c index bb88f3008..aa89d89a3 100644 --- a/drivers/spi/bfin_spi.c +++ b/drivers/spi/bfin_spi.c @@ -162,21 +162,22 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,  	if (!spi_cs_is_valid(bus, cs))  		return NULL; -	if (bus >= ARRAY_SIZE(pins) || pins[bus] == NULL) { -		debug("%s: invalid bus %u\n", __func__, bus); -		return NULL; -	}  	switch (bus) {  #ifdef SPI0_CTL -		case 0: mmr_base = SPI0_CTL; break; +	case 0: +		mmr_base = SPI0_CTL; break;  #endif  #ifdef SPI1_CTL -		case 1: mmr_base = SPI1_CTL; break; +	case 1: +		mmr_base = SPI1_CTL; break;  #endif  #ifdef SPI2_CTL -		case 2: mmr_base = SPI2_CTL; break; +	case 2: +		mmr_base = SPI2_CTL; break;  #endif -		default: return NULL; +	default: +		debug("%s: invalid bus %u\n", __func__, bus); +		return NULL;  	}  	bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs); diff --git a/drivers/spi/bfin_spi6xx.c b/drivers/spi/bfin_spi6xx.c index c25c4a9ae..07b833d3a 100644 --- a/drivers/spi/bfin_spi6xx.c +++ b/drivers/spi/bfin_spi6xx.c @@ -154,10 +154,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,  	if (!spi_cs_is_valid(bus, cs))  		return NULL; -	if (bus >= ARRAY_SIZE(pins) || pins[bus] == NULL) { -		debug("%s: invalid bus %u\n", __func__, bus); -		return NULL; -	}  	switch (bus) {  #ifdef SPI0_REGBASE  	case 0: @@ -175,6 +171,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,  		break;  #endif  	default: +		debug("%s: invalid bus %u\n", __func__, bus);  		return NULL;  	} diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 699c57eb6..4d5def2d3 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -529,18 +529,18 @@ static int process_nodes(const void *blob, int node_list[], int count)   * @param node		SPI peripheral node to use   * @return 0 if ok, -1 on error   */ -struct spi_slave *spi_setup_slave_fdt(const void *blob, int node, -		unsigned int cs, unsigned int max_hz, unsigned int mode) +struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node, +				      int spi_node)  {  	struct spi_bus *bus;  	unsigned int i;  	for (i = 0, bus = spi_bus; i < bus_count; i++, bus++) { -		if (bus->node == node) -			return spi_setup_slave(i, cs, max_hz, mode); +		if (bus->node == spi_node) +			return spi_base_setup_slave_fdt(blob, i, slave_node);  	} -	debug("%s: Failed to find bus node %d\n", __func__, node); +	debug("%s: Failed to find bus node %d\n", __func__, spi_node);  	return NULL;  } diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c new file mode 100644 index 000000000..7895305a0 --- /dev/null +++ b/drivers/spi/sandbox_spi.c @@ -0,0 +1,204 @@ +/* + * Simulate a SPI port + * + * Copyright (c) 2011-2013 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> +#include <os.h> + +#include <asm/errno.h> +#include <asm/spi.h> +#include <asm/state.h> + +#ifndef CONFIG_SPI_IDLE_VAL +# define CONFIG_SPI_IDLE_VAL 0xFF +#endif + +struct sandbox_spi_slave { +	struct spi_slave slave; +	const struct sandbox_spi_emu_ops *ops; +	void *priv; +}; + +#define to_sandbox_spi_slave(s) container_of(s, struct sandbox_spi_slave, slave) + +const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus, +				   unsigned long *cs) +{ +	char *endp; + +	*bus = simple_strtoul(arg, &endp, 0); +	if (*endp != ':' || *bus >= CONFIG_SANDBOX_SPI_MAX_BUS) +		return NULL; + +	*cs = simple_strtoul(endp + 1, &endp, 0); +	if (*endp != ':' || *cs >= CONFIG_SANDBOX_SPI_MAX_CS) +		return NULL; + +	return endp + 1; +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ +	return bus < CONFIG_SANDBOX_SPI_MAX_BUS && +		cs < CONFIG_SANDBOX_SPI_MAX_CS; +} + +void spi_cs_activate(struct spi_slave *slave) +{ +	struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave); + +	debug("sandbox_spi: activating CS\n"); +	if (sss->ops->cs_activate) +		sss->ops->cs_activate(sss->priv); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ +	struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave); + +	debug("sandbox_spi: deactivating CS\n"); +	if (sss->ops->cs_deactivate) +		sss->ops->cs_deactivate(sss->priv); +} + +void spi_init(void) +{ +} + +void spi_set_speed(struct spi_slave *slave, uint hz) +{ +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, +		unsigned int max_hz, unsigned int mode) +{ +	struct sandbox_spi_slave *sss; +	struct sandbox_state *state = state_get_current(); +	const char *spec; + +	if (!spi_cs_is_valid(bus, cs)) { +		debug("sandbox_spi: Invalid SPI bus/cs\n"); +		return NULL; +	} + +	sss = spi_alloc_slave(struct sandbox_spi_slave, bus, cs); +	if (!sss) { +		debug("sandbox_spi: Out of memory\n"); +		return NULL; +	} + +	spec = state->spi[bus][cs].spec; +	sss->ops = state->spi[bus][cs].ops; +	if (!spec || !sss->ops || sss->ops->setup(&sss->priv, spec)) { +		free(sss); +		printf("sandbox_spi: unable to locate a slave client\n"); +		return NULL; +	} + +	return &sss->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ +	struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave); + +	debug("sandbox_spi: releasing slave\n"); + +	if (sss->ops->free) +		sss->ops->free(sss->priv); + +	free(sss); +} + +static int spi_bus_claim_cnt[CONFIG_SANDBOX_SPI_MAX_BUS]; + +int spi_claim_bus(struct spi_slave *slave) +{ +	if (spi_bus_claim_cnt[slave->bus]++) { +		printf("sandbox_spi: error: bus already claimed: %d!\n", +		       spi_bus_claim_cnt[slave->bus]); +	} + +	return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +	if (--spi_bus_claim_cnt[slave->bus]) { +		printf("sandbox_spi: error: bus freed too often: %d!\n", +		       spi_bus_claim_cnt[slave->bus]); +	} +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, +		void *din, unsigned long flags) +{ +	struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave); +	uint bytes = bitlen / 8, i; +	int ret = 0; +	u8 *tx = (void *)dout, *rx = din; + +	if (bitlen == 0) +		goto done; + +	/* we can only do 8 bit transfers */ +	if (bitlen % 8) { +		printf("sandbox_spi: xfer: invalid bitlen size %u; needs to be 8bit\n", +		       bitlen); +		flags |= SPI_XFER_END; +		goto done; +	} + +	if (flags & SPI_XFER_BEGIN) +		spi_cs_activate(slave); + +	/* make sure rx/tx buffers are full so clients can assume */ +	if (!tx) { +		debug("sandbox_spi: xfer: auto-allocating tx scratch buffer\n"); +		tx = malloc(bytes); +		if (!tx) { +			debug("sandbox_spi: Out of memory\n"); +			return -ENOMEM; +		} +	} +	if (!rx) { +		debug("sandbox_spi: xfer: auto-allocating rx scratch buffer\n"); +		rx = malloc(bytes); +		if (!rx) { +			debug("sandbox_spi: Out of memory\n"); +			return -ENOMEM; +		} +	} + +	debug("sandbox_spi: xfer: bytes = %u\n tx:", bytes); +	for (i = 0; i < bytes; ++i) +		debug(" %u:%02x", i, tx[i]); +	debug("\n"); + +	ret = sss->ops->xfer(sss->priv, tx, rx, bytes); + +	debug("sandbox_spi: xfer: got back %i (that's %s)\n rx:", +	      ret, ret ? "bad" : "good"); +	for (i = 0; i < bytes; ++i) +		debug(" %u:%02x", i, rx[i]); +	debug("\n"); + +	if (tx != dout) +		free(tx); +	if (rx != din) +		free(rx); + + done: +	if (flags & SPI_XFER_END) +		spi_cs_deactivate(slave); + +	return ret; +} diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b76a26cef..7ddea9b02 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -5,6 +5,7 @@   */  #include <common.h> +#include <fdtdec.h>  #include <malloc.h>  #include <spi.h> @@ -37,3 +38,21 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,  	return ptr;  } + +#ifdef CONFIG_OF_SPI +struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum, +					   int node) +{ +	int cs, max_hz, mode = 0; + +	cs = fdtdec_get_int(blob, node, "reg", -1); +	max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 100000); +	if (fdtdec_get_bool(blob, node, "spi-cpol")) +		mode |= SPI_CPOL; +	if (fdtdec_get_bool(blob, node, "spi-cpha")) +		mode |= SPI_CPHA; +	if (fdtdec_get_bool(blob, node, "spi-cs-high")) +		mode |= SPI_CS_HIGH; +	return spi_setup_slave(busnum, cs, max_hz, mode); +} +#endif diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index a80a6966b..037484104 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -67,6 +67,7 @@   */  #define CONFIG_SYS_FSL_DDR2  #ifdef CONFIG_SYS_FSL_DDR2 +#define CONFIG_SYS_FSL_DDRC_GEN2  #define CONFIG_SYS_SPD_BUS_NUM	0  #define SPD_EEPROM_ADDRESS1	0x52  #define SPD_EEPROM_ADDRESS2	0x51 diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h index eab386add..1ed5e1df2 100644 --- a/include/configs/P1010RDB.h +++ b/include/configs/P1010RDB.h @@ -173,7 +173,7 @@  #define CONFIG_SYS_NUM_ADDR_MAP		16	/* number of TLB1 entries */  #endif -#define CONFIG_SYS_MEMTEST_START	0x00000000	/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START	0x00200000	/* memtest works on */  #define CONFIG_SYS_MEMTEST_END		0x1fffffff  #define CONFIG_PANIC_HANG		/* do not reset board on panic */ diff --git a/include/configs/T2080QDS.h b/include/configs/T2080QDS.h index ad0981697..bff001f43 100644 --- a/include/configs/T2080QDS.h +++ b/include/configs/T2080QDS.h @@ -155,7 +155,7 @@ unsigned long get_board_ddr_clk(void);  #define CONFIG_CHIP_SELECTS_PER_CTRL	(4 * CONFIG_DIMM_SLOTS_PER_CTLR)  #define CONFIG_DDR_SPD  #define CONFIG_SYS_FSL_DDR3 -#define CONFIG_FSL_DDR_INTERACTIVE +#undef CONFIG_FSL_DDR_INTERACTIVE  #define CONFIG_SYS_SPD_BUS_NUM	0  #define CONFIG_SYS_SDRAM_SIZE	2048	/* for fixed parameter use */  #define SPD_EEPROM_ADDRESS1	0x51 diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index 79a607937..57b620d48 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -73,12 +73,12 @@   * the MPL VCMA9 is equipped with an ATMEL 24C256 EEPROM at   * address 0x50 with 16bit addressing   */ -#define CONFIG_HARD_I2C				/* I2C with hardware support */ -#define CONFIG_SYS_I2C_SPEED		100000	/* I2C speed */ -#define CONFIG_SYS_I2C_SLAVE		0x7F	/* I2C slave addr */ +#define CONFIG_SYS_I2C  /* we use the built-in I2C controller */ -#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED    100000	/* I2C speed */ +#define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x7F	/* I2C slave addr */  #define CONFIG_SYS_I2C_EEPROM_ADDR	0x50  #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2 diff --git a/include/configs/arndale.h b/include/configs/arndale.h index f0b9f944e..a3cb56b8b 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -210,13 +210,12 @@  /* I2C */  #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_HARD_I2C +#define CONFIG_SYS_I2C  #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_SPEED	100000		/* 100 Kbps */ -#define CONFIG_DRIVER_S3C24X0_I2C -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED	100000		/* 100 Kbps */ +#define CONFIG_SYS_I2C_S3C24X0  #define CONFIG_MAX_I2C_NUM	8 -#define CONFIG_SYS_I2C_SLAVE    0x0 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x0  #define CONFIG_I2C_EDID  /* PMIC */ diff --git a/include/configs/bf506f-ezkit.h b/include/configs/bf506f-ezkit.h index 77b6735a7..5ad3ee70d 100644 --- a/include/configs/bf506f-ezkit.h +++ b/include/configs/bf506f-ezkit.h @@ -94,6 +94,7 @@  #define CONFIG_DCACHE_OFF  #define CONFIG_UART_CONSOLE	0  #define CONFIG_BAUDRATE 115200 +#define CONFIG_BFIN_SERIAL  #define CONFIG_CMD_MEMORY  #undef CONFIG_GZIP diff --git a/include/configs/bf525-ucr2.h b/include/configs/bf525-ucr2.h index 1f65130f6..008f4b5ec 100644 --- a/include/configs/bf525-ucr2.h +++ b/include/configs/bf525-ucr2.h @@ -85,6 +85,7 @@  #define CONFIG_UART_CONSOLE	0  #define CONFIG_BAUDRATE		115200 +#define CONFIG_BFIN_SERIAL  #define CONFIG_BOOTARGS		"root=/dev/mtdblock0 rw"  #define CONFIG_BOOTCOMMAND	"run sfboot"  #define CONFIG_BOOTDELAY	5 diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h index a22c86842..f5b965829 100644 --- a/include/configs/bf533-stamp.h +++ b/include/configs/bf533-stamp.h @@ -80,33 +80,8 @@  /*   * Software (bit-bang) I2C driver configuration   */ -#define PF_SCL			PF3 -#define PF_SDA			PF2 -#define I2C_INIT		(*pFIO_DIR |=  PF_SCL); asm("ssync;") -#define I2C_ACTIVE		(*pFIO_DIR |=  PF_SDA); \ -				*pFIO_INEN &= ~PF_SDA; asm("ssync;") -#define I2C_TRISTATE		(*pFIO_DIR &= ~PF_SDA); \ -				*pFIO_INEN |= PF_SDA; asm("ssync;") -#define I2C_READ		((volatile)(*pFIO_FLAG_D & PF_SDA) != 0); \ -				asm("ssync;") -#define I2C_SDA(bit)	if (bit) { \ -				*pFIO_FLAG_S = PF_SDA; \ -				asm("ssync;"); \ -				} \ -			else	{ \ -				*pFIO_FLAG_C = PF_SDA; \ -				asm("ssync;"); \ -				} -#define I2C_SCL(bit)	if (bit) { \ -				*pFIO_FLAG_S = PF_SCL; \ -				asm("ssync;"); \ -				} \ -			else	{ \ -				*pFIO_FLAG_C = PF_SCL; \ -				asm("ssync;"); \ -				} -#define I2C_DELAY		udelay(5)	/* 1/4 I2C clock duration */ - +#define CONFIG_SOFT_I2C_GPIO_SCL	GPIO_PF3 +#define CONFIG_SOFT_I2C_GPIO_SDA	GPIO_PF2  /*   * Flash Settings diff --git a/include/configs/bf537-minotaur.h b/include/configs/bf537-minotaur.h index feb9d7344..156eeabb0 100644 --- a/include/configs/bf537-minotaur.h +++ b/include/configs/bf537-minotaur.h @@ -136,6 +136,7 @@  #define CONFIG_BAUDRATE		57600  #define CONFIG_UART_CONSOLE	0 +#define CONFIG_BFIN_SERIAL  #define CONFIG_PANIC_HANG	1  #define CONFIG_RTC_BFIN		1 diff --git a/include/configs/bf537-srv1.h b/include/configs/bf537-srv1.h index 1de8ffe2d..e12d761a2 100644 --- a/include/configs/bf537-srv1.h +++ b/include/configs/bf537-srv1.h @@ -136,6 +136,7 @@  #define CONFIG_BAUDRATE		115200  #define CONFIG_UART_CONSOLE	0 +#define CONFIG_BFIN_SERIAL  #define CONFIG_PANIC_HANG	1  #define CONFIG_RTC_BFIN		1 diff --git a/include/configs/blackstamp.h b/include/configs/blackstamp.h index 5b3aac795..7de425349 100644 --- a/include/configs/blackstamp.h +++ b/include/configs/blackstamp.h @@ -195,6 +195,7 @@  #define CONFIG_BAUDRATE		57600  #define CONFIG_LOADS_ECHO	1  #define CONFIG_UART_CONSOLE	0 +#define CONFIG_BFIN_SERIAL  /*   * I2C settings diff --git a/include/configs/cm-bf548.h b/include/configs/cm-bf548.h index 3c9eeb58a..7f27eda41 100644 --- a/include/configs/cm-bf548.h +++ b/include/configs/cm-bf548.h @@ -118,6 +118,8 @@  #define CONFIG_BOOTCOMMAND	"run flashboot"  #define FLASHBOOT_ENV_SETTINGS	"flashboot=bootm 0x20040000\0" +#define CONFIG_ADI_GPIO2 +  #ifndef __ADSPBF542__  /* Don't waste time transferring a logo over the UART */  # if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART) diff --git a/include/configs/dnp5370.h b/include/configs/dnp5370.h index d0e72e3e1..4f2c742a5 100644 --- a/include/configs/dnp5370.h +++ b/include/configs/dnp5370.h @@ -103,6 +103,7 @@  #define CONFIG_DNP5370_EXT_WD_DISABLE 1  #define CONFIG_UART_CONSOLE 0 +#define CONFIG_BFIN_SERIAL  #define CONFIG_BAUDRATE     115200  #define CONFIG_BOOTCOMMAND  "bootm 0x20030000"  #define CONFIG_BOOTARGS     "console=ttyBF0,115200 root=/dev/mtdblock3 rootfstype=ext2" diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index dee18a750..8fb904cdd 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -250,13 +250,13 @@  /* I2C */  #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_HARD_I2C +#define CONFIG_SYS_I2C  #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_SPEED	100000		/* 100 Kbps */ -#define CONFIG_DRIVER_S3C24X0_I2C +#define CONFIG_SYS_I2C_S3C24X0_SPEED	100000		/* 100 Kbps */ +#define CONFIG_SYS_I2C_S3C24X0  #define CONFIG_I2C_MULTI_BUS  #define CONFIG_MAX_I2C_NUM	8 -#define CONFIG_SYS_I2C_SLAVE	0x0 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x0  #define CONFIG_I2C_EDID  /* PMIC */ @@ -278,6 +278,7 @@  #define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0  #define CONFIG_SF_DEFAULT_SPEED		50000000  #define EXYNOS5_SPI_NUM_CONTROLLERS	5 +#define CONFIG_OF_SPI  #endif  #ifdef CONFIG_ENV_IS_IN_SPI_FLASH diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index a4edc624b..7e78a231d 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -71,6 +71,16 @@  #define CONFIG_ENV_SIZE		8192  #define CONFIG_ENV_IS_NOWHERE +/* SPI */ +#define CONFIG_SANDBOX_SPI +#define CONFIG_CMD_SF +#define CONFIG_CMD_SF_TEST +#define CONFIG_CMD_SPI +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_SANDBOX +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SPI_FLASH_WINBOND +  /* Memory things - we don't really want a memory test */  #define CONFIG_SYS_LOAD_ADDR		0x00000000  #define CONFIG_SYS_MEMTEST_START	0x00100000 diff --git a/include/configs/trats.h b/include/configs/trats.h index 8ff9800b1..08771422e 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -16,6 +16,7 @@   */  #define CONFIG_SAMSUNG		/* in a SAMSUNG core */  #define CONFIG_S5P		/* which is in a S5P Family */ +#define CONFIG_EXYNOS4		/* which is in a EXYNOS4XXX */  #define CONFIG_EXYNOS4210	/* which is in a EXYNOS4210 */  #define CONFIG_TRATS		/* working with TRATS */  #define CONFIG_TIZEN		/* TIZEN lib */ @@ -268,31 +269,21 @@  #define CONFIG_SYS_CACHELINE_SIZE       32  #define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED	100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE	0xFE +#define CONFIG_MAX_I2C_NUM		8  #define CONFIG_SYS_I2C_SOFT		/* I2C bit-banged */  #define CONFIG_SYS_I2C_SOFT_SPEED	50000 -#define CONFIG_SYS_I2C_SOFT_SLAVE	0xFE -#define I2C_SOFT_DECLARATIONS2 -#define CONFIG_SYS_I2C_SOFT_SPEED_2     50000 -#define CONFIG_SYS_I2C_SOFT_SLAVE_2     0x7F +#define CONFIG_SYS_I2C_SOFT_SLAVE	0x7F  #define CONFIG_SOFT_I2C_READ_REPEATED_START  #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SOFT_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS	15  #include <asm/arch/gpio.h> -/* I2C PMIC */ -#define CONFIG_SOFT_I2C_I2C5_SCL exynos4_gpio_part1_get_nr(b, 7) -#define CONFIG_SOFT_I2C_I2C5_SDA exynos4_gpio_part1_get_nr(b, 6) -  /* I2C FG */ -#define CONFIG_SOFT_I2C_I2C9_SCL exynos4_gpio_part2_get_nr(y4, 1) -#define CONFIG_SOFT_I2C_I2C9_SDA exynos4_gpio_part2_get_nr(y4, 0) - -#define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin() -#define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin() -#define I2C_INIT multi_i2c_init() +#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part2_get_nr(y4, 1) +#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part2_get_nr(y4, 0)  #define CONFIG_POWER  #define CONFIG_POWER_I2C diff --git a/include/configs/trats2.h b/include/configs/trats2.h index c49a969e3..5d86a3d4e 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -278,30 +278,25 @@  #include <asm/arch/gpio.h>  #define CONFIG_SYS_I2C -#define CONFIG_SYS_I2C_SOFT		/* I2C bit-banged */ +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED	100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE	0 +#define CONFIG_MAX_I2C_NUM		8 +#define CONFIG_SYS_I2C_SOFT  #define CONFIG_SYS_I2C_SOFT_SPEED	50000  #define CONFIG_SYS_I2C_SOFT_SLAVE	0x00  #define I2C_SOFT_DECLARATIONS2  #define CONFIG_SYS_I2C_SOFT_SPEED_2     50000  #define CONFIG_SYS_I2C_SOFT_SLAVE_2     0x00 -#define I2C_SOFT_DECLARATIONS3 -#define CONFIG_SYS_I2C_SOFT_SPEED_3     50000 -#define CONFIG_SYS_I2C_SOFT_SLAVE_3     0x00  #define CONFIG_SOFT_I2C_READ_REPEATED_START  #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SOFT_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS		15 -#define CONFIG_SOFT_I2C_I2C5_SCL exynos4x12_gpio_part1_get_nr(d0, 3) -#define CONFIG_SOFT_I2C_I2C5_SDA exynos4x12_gpio_part1_get_nr(d0, 2) -#define CONFIG_SOFT_I2C_I2C9_SCL exynos4x12_gpio_part1_get_nr(f1, 4) -#define CONFIG_SOFT_I2C_I2C9_SDA exynos4x12_gpio_part1_get_nr(f1, 5) -#define CONFIG_SOFT_I2C_I2C10_SCL exynos4x12_gpio_part2_get_nr(m2, 1) -#define CONFIG_SOFT_I2C_I2C10_SDA exynos4x12_gpio_part2_get_nr(m2, 0) -#define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin() -#define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin() -#define I2C_INIT multi_i2c_init() +#ifndef __ASSEMBLY__ +int get_soft_i2c_scl_pin(void); +int get_soft_i2c_sda_pin(void); +#endif +#define CONFIG_SOFT_I2C_GPIO_SCL	get_soft_i2c_scl_pin() +#define CONFIG_SOFT_I2C_GPIO_SDA	get_soft_i2c_sda_pin()  /* POWER */  #define CONFIG_POWER diff --git a/include/dwmmc.h b/include/dwmmc.h index 6c91143e9..a02dd67c1 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -141,6 +141,7 @@ struct dwmci_host {  	struct mmc *mmc;  	void (*clksel)(struct dwmci_host *host); +	void (*board_init)(struct dwmci_host *host);  	unsigned int (*get_mmc_clk)(int dev_index);  }; diff --git a/include/faraday/ftsdc021.h b/include/faraday/ftsdc021.h new file mode 100644 index 000000000..de8e25083 --- /dev/null +++ b/include/faraday/ftsdc021.h @@ -0,0 +1,13 @@ +/* + * (C) Copyright 2013 Faraday Technology + * Dante Su <dantesu@faraday-tech.com> + * + * SPDX-License-Identifier:    GPL-2.0+ + */ + +#ifndef __FTSDC021_H +#define __FTSDC021_H + +int ftsdc021_sdhci_init(u32 regbase); + +#endif /* __FTSDC021_H */ diff --git a/include/spi.h b/include/spi.h index e2563c99f..aba792244 100644 --- a/include/spi.h +++ b/include/spi.h @@ -259,13 +259,24 @@ static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte)   * spi_free_slave() to free it later.   *   * @param blob:		Device tree blob - * @param node:		SPI peripheral node to use - * @param cs:		Chip select to use - * @param max_hz:	Maximum SCK rate in Hz (0 for default) - * @param mode:		Clock polarity, clock phase and other parameters + * @param slave_node:	Slave node to use + * @param spi_node:	SPI peripheral node to use   * @return pointer to new spi_slave structure   */ -struct spi_slave *spi_setup_slave_fdt(const void *blob, int node, -		unsigned int cs, unsigned int max_hz, unsigned int mode); +struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node, +				      int spi_node); + +/** + * spi_base_setup_slave_fdt() - helper function to set up a SPI slace + * + * This decodes SPI properties from the slave node to determine the + * chip select and SPI parameters. + * + * @blob:	Device tree blob + * @busnum:	Bus number to use + * @node:	Device tree node for the SPI bus + */ +struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum, +					   int node);  #endif	/* _SPI_H_ */ diff --git a/include/spi_flash.h b/include/spi_flash.h index 25ca8f177..afc3a5809 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -67,6 +67,19 @@ struct spi_flash {  struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,  		unsigned int max_hz, unsigned int spi_mode); + +/** + * Set up a new SPI flash from an fdt node + * + * @param blob		Device tree blob + * @param slave_node	Pointer to this SPI slave node in the device tree + * @param spi_node	Cached pointer to the SPI interface this node belongs + *			to + * @return 0 if ok, -1 on error + */ +struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node, +				      int spi_node); +  void spi_flash_free(struct spi_flash *flash);  static inline int spi_flash_read(struct spi_flash *flash, u32 offset, |